I am new to Python Tuples, and doing a learning exercise on the same. How should I print the following pattern when the input is the String HI,HELLO,WELCOME.
(('HI', 'HELLO', 'WELCOME'),)
((('HI', 'HELLO', 'WELCOME'),),)
(((('HI', 'HELLO', 'WELCOME'),),),)
My Attempt
n = input()
arr = tuple(raw_input().split())
arr1 = list()
print arr
while(n>0) :
print(tuple(arr,))
n -= 1
just define (or create) a tuple at start, then nest it on itself (reusing the same variable):
n = 3
arr = ('HI','HELLO','WELCOME') # or tuple(raw_input().split())
while(n>0):
arr = (arr,) # that's enough to create a tuple inside the tuple
print(arr)
n -= 1
result:
(('HI', 'HELLO', 'WELCOME'),)
((('HI', 'HELLO', 'WELCOME'),),)
(((('HI', 'HELLO', 'WELCOME'),),),)
Just nest your first tuple in another tuple each iteration.
>>> n = 3
>>> tup = ('HI', 'HELLO', 'WELCOME')
>>> for _ in range(n):
tup = tup,
print(tup)
(('HI', 'HELLO', 'WELCOME'),)
((('HI', 'HELLO', 'WELCOME'),),)
(((('HI', 'HELLO', 'WELCOME'),),),)
>>>
As you can see, on each iteration the tuple is nested a level deeper. The problem with your original method is that you didn't reassign the new nested tuple back to arr, so your tuple's never nested.
In your attempt you were always printing the same thing. You need to update the tuple on each iteration, so you have to have
while n>0:
arr = (arr,)
print(arr)
n=-1
Related
I have a list:
greeting = ['hello','my','name','is','bob','how','are','you']
I want to define a function that will find the first and last index of a sublist in this list. Thus:
find_sub_list(['my','name','is'], greeting)
should return:
1, 3
Suggestions?
If you want multiple matches, this works:
greeting = ['hello','my','name','is','bob','how','are','you','my','name','is']
def find_sub_list(sl,l):
results=[]
sll=len(sl)
for ind in (i for i,e in enumerate(l) if e==sl[0]):
if l[ind:ind+sll]==sl:
results.append((ind,ind+sll-1))
return results
print find_sub_list(['my','name','is'], greeting)
# [(1, 3), (8, 10)]
Or if you just want the first match:
greeting = ['hello','my','name','is','bob','how','are','you','my','name','is']
def find_sub_list(sl,l):
sll=len(sl)
for ind in (i for i,e in enumerate(l) if e==sl[0]):
if l[ind:ind+sll]==sl:
return ind,ind+sll-1
print find_sub_list(['my','name','is'], greeting)
# (1, 3)
Slice the list:
>>> greeting[0:3]
['hello', 'my', 'name']
>>> greeting[1:4]
['my', 'name', 'is']
>>> greeting[1:4] == ['my','name','is']
True
This should get your started:
for n in range(len(greeting) - len(sub_list) + 1):
...
If you're sure that your list will always be in your sublist you can just do:
def find_sub_list(sub_list,this_list):
return (this_list.index(sub_list[0]),len(sub_list))
If you want to be checking the items in the sublist exist in the list then use:
def find_sub_list(sub_list,this_list):
if set(sub_list).issubset(set(this_list)):
return(this_list.index(sub_list[0]),len(sub_list))
else:
return False
Lastly, if the order of the items in the sub_list is also going to be unknown then use this:
def find_sub_list(sub_list,this_list):
if sub_list[0] in this_list:
for i,item in enumerate(sub_list[1:]):
if item not in this_list[this_list.index(sub_list[i]):]:
return False
return(this_list.index(sub_list[0]),len(sub_list))
Now, the items have to be in the right order for the function not to return false.
Following is a solution if only the indices of the first and the last entry are to be returned:
def find_sub_list(subl, l):
ind_subl = [i for i in range(len(l)) if l[i] in subl]
return [ind_subl[0], ind_subl[-1]]
print find_sub_list(['my', 'name', 'is'], greeting)
# [1, 3]
I have an tuple containing 100 string values (say). Now, I want to check if two string elements there in the tuple are same?
I tried to do something like this with nested loops:
def hasDuplicates(arr: tuple):
ctr = 0
# arr looks something like this & len(arr) == 100
# arr = ('abc', 'bcd', 'sdf', 'abc', 'pqr', ...)
for m in arr:
for n in arr:
if n == m:
ctr += 1
# while looping, len(arr) times every element
# will be compared with itself
if ctr > len(arr):
return True
return False
...which worked but I think there is a better work around for this. Can anyone provide a better solution to this? :)
If I understand correctly, you can just convert your tuple to a set and check whether it has the same length as the original tuple.
def has_duplicates(iterable):
l = list(iterable) # in case iterable is an iterator
return len(set(l)) != len(l)
Demo:
>>> tup = ('abc', 'bcd', 'sdf', 'abc', 'pqr')
>>> has_duplicates(tup)
>>> True
>>> has_duplicates(range(100))
>>> False
Won't work for infinite iterators :)
~edit~
A more general version that does not have to build a potentially long list and set upfront:
def has_duplicates(iterable):
seen = set()
for x in iterable:
if x in seen:
return True
seen.add(x)
return False
Of course, both versions require the elements of your iterable to be hashable.
You can also check this using any keyword and count method from list object:
arr = ('abc', 'bcd', 'sdf', 'abc', 'pqr')
def sameStrings(arr):
return any(arr.count(elem)>1 for elem in list(arr))
print(sameStrings(arr))
Output:
True
Edit
Updating answer with proposed solution by #timgeb using Counter from collections module:
from collections import Counter
arr = ('abc', 'bcd', 'sdf', 'abc', 'pqr')
def sameStrings(arr):
myCounter = Counter(list(arr))
return max(myCounter.values())>1
print(sameStrings(arr))
Output:
True
has_duplicates = len(set(some_tuple)) == 1
I have
char=str('DOTR')
and
a=range(0,18)
How could I combine them to create a list with:
mylist=['DOTR00','DOTR01',...,'DOTR17']
If I combine them in a for loop then I lose the leading zero.
Use zfill:
>>> string = "DOTR"
>>> for i in range(0, 18):
... print("DOTR{}".format(str(i).zfill(2)))
...
DOTR00
DOTR01
DOTR02
DOTR03
DOTR04
DOTR05
DOTR06
DOTR07
DOTR08
DOTR09
DOTR10
DOTR11
DOTR12
DOTR13
DOTR14
DOTR15
DOTR16
DOTR17
>>>
And if you want a list:
>>> my_list = ["DOTR{}".format(str(i).zfill(2)) for i in range(18)]
>>> my_list
['DOTR00', 'DOTR01', 'DOTR02', 'DOTR03', 'DOTR04', 'DOTR05', 'DOTR06', 'DOTR07', 'DOTR08', 'DOTR09', 'DOTR10', 'DOTR11', 'DOTR12', 'DOTR13', 'DOTR14', 'DOTR15', 'DOTR16', 'DOTR17']
>>>
You can do it using a list comprehension like so:
>>> mylist = [char+'{0:02}'.format(i) for i in a]
>>> mylist
['DOTR00', 'DOTR01', 'DOTR02', 'DOTR03', 'DOTR04', 'DOTR05', 'DOTR06', 'DOTR07', 'DOTR08', 'DOTR09', 'DOTR10', 'DOTR11', 'DOTR12', 'DOTR13', 'DOTR14', 'DOTR15', 'DOTR16', 'DOTR17']
Simply use list comprehension and format:
mylist = ['DOTR%02d'%i for i in range(18)]
Or given that char and a are variable:
mylist = ['%s%02d'%(char,i) for i in a]
You can, as #juanpa.arrivillaga also specify it as:
mylist = ['{}{:02d}'.format(char,i) for i in a]
List comprehension is a concept where you write an expression:
[<expr> for <var> in <iterable>]
Python iterates over the <iterable> and unifies it with <var> (here i), next it calls the <expr> and the result is appended to the list until the <iterable> is exhausted.
can do like this
char = str('DOTR')
a=range(0,18)
b = []
for i in a:
b.append(char + str(i).zfill(2))
print(b)
I am new to python and want to write a function that takes in a string and returns a list of all possible capitalizations of the string. here it is:
def transform_capitalize(st):
l=[]
l.append(st.lower())
newl=l
length=len(st)
for x in range(0,length):
for i in l:
newl.append(i[:x]+i[x].upper()+i[(x+1):])
l=newl
return l
The logic is as follows:
Take the string and convert to lower cast then put into a list
then have a loop within a loop get the possibilities of each letter being uppercase one at a time and update the list after each letter position.
So for Foo as an example
l=['foo'] and length is 3 so from 0 to 2 take every element in the list and capitalize the letter in the ith position, append these to the newl, then update the list after all capitalizations at that position have been made
so when i = 0 the list should be ["foo","Foo"] at the end.
For i = 1 it should be ["foo","Foo""fOo","FOo"] and for 2 it should be ['foo', 'Foo', 'fOo', 'FOo', 'foO', 'FoO', 'fOO', 'FOO']. The order doesn't matter, but more some reason I'm getting a memory error so I'm assuming its some infinite loop.
Can anyone tell me whats wrong?
These 2 lines are the problem:
newl=l
l = newl
When you assign a variable an array, the default behavior is for the variable to act as a reference, not a copy. It means, if you assign a an empty list , then you assign a to b, appending anything to b or a is one and same.
a = []
b = a
b.append("hello")
print(a) # prints ["hello"]
To copy an array in python, you use slicing:
a = []
b = a[:] #here
b.append("hello")
print(a) # prints []
Now, changing reference assignment to copying when intended:
def transform_capitalize(st):
l=[]
l.append(st.lower())
newl=l[:]
length=len(st)
for x in range(0,length):
for i in l:
newl.append(i[:x]+i[x].upper()+i[(x+1):])
l=newl[:]
return l
transform_capitalize("hello"); #['hello', 'Hello', 'hEllo', 'HEllo', 'heLlo', 'HeLlo', 'hELlo', 'HELlo', 'helLo', 'HelLo', 'hElLo', 'HElLo', 'heLLo', 'HeLLo', 'hELLo', 'HELLo', 'hellO', 'HellO', 'hEllO', 'HEllO', 'heLlO', 'HeLlO', 'hELlO', 'HELlO', 'helLO', 'HelLO', 'hElLO', 'HElLO', 'heLLO', 'HeLLO', 'hELLO', 'HELLO']
A recursive solution could also be used:
def transform_capitalize(st):
result = []
if len(st) > 0:
head = st[0]
tails = transform_capitalize(st[1:])
for t in tails:
result.append( head.lower() + t )
result.append( head.upper() + t )
else:
result = [ '' ]
return result
Given an empty string, it will return a single empty string. It could be modified if this is not what we want (by placing the stop condition at length 1 instead of 0).
I'm bored, so here is a "Batteries Included" version of your function:
from itertools import product
from string import upper, lower
def capitalize(word):
word = word.lower()
for p in product([upper, lower], repeat=len(word)):
yield ''.join(fn(letter) for fn, letter in zip(p, word))
if __name__=='__main__':
print list(capitalize('foo'))
These three functions are apart of my study guide and would greatly appreciate some assistance.
In each case, the function returns a value (so use the return statement): it does not print the value (no print statement) or mutate (change the value of) any of its arguments.
1) The repl function takes three arguments:
◦old is any value;
◦new is any value;
◦xs is a list.
Example:
>>> repl('zebra', 'donkey', ['mule', 'horse', 'zebra', 'sheep', 'zebra'])
['mule', 'horse', 'donkey', 'sheep', 'donkey']
It returns a new list formed by replacing every occurrence of old in xs with new.
It must not mutate the list xs; i.e., after return from the function, the actual argument given for xs must be what it was before.
>>> friends = ['jules', 'james', 'janet', 'jerry']
>>> repl('james', 'henry', friends)
['jules', 'henry', 'janet', 'jerry']
>>> friends
['jules', 'james', 'janet', 'jerry']
2) The search function looks for a value in a list. It takes two arguments:
◦y is the value being searched for.
◦xs is the list being searched in.
It returns the index of the first occurrence of y in xs, if it occurs; −1 otherwise.
Examples:
>>> words = ['four', 'very', 'black', 'sheep']
>>> search('four', words)
0
>>> search('sheep', words)
3
>>> search('horse', words)
-1
3) The doubles function is given a list of numbers and returns a new list containing the doubles of every number in the given list.
Example:
>>> doubles([1, 3, 7, 10])
[2, 6, 14, 20]
It must not mutate the given list:
>>> salaries = [5000, 7500, 15000]
>>> doubles(salaries)
[10000, 15000, 30000]
>>> salaries
[5000, 7500, 15000]
This is to be done without using any list methods except append. (In particular, you may not use the index or count for the search function.)
Although you can use the list len function, and the list operations +, *, indexing, slicing, and == for comparing lists or elements. You will need to use some of these but not all.
Any help is greatly appreciated like I mentioned in the introduction.
So far all I have is.
def repl (find, replacement, s):
newString = ''
for c in s:
if c != find:
newString = newString + c
else:
newString = newString + replacement
return newString
def search(y, xs):
n = len(xs)
for i in range(n):
if xs[i] == y:
return i
return -1
and....
def search(key,my_list):
if key in my_list:
return my_list.index(key)
else:
return
I'm not sure what needs to be returned after the else statement.
def relp(old,new,my_list):
final = []
for x in my_list:
if x is old:
final.append(new)
else:
final.append(x)
return final
def search(key,my_list):
if key in my_list:
return my_list.index(key)
else:
return -1
def doubles(my_list):
return[x*x for x in my_list]
I suspect this lesson is about list comprehensions
doubles = lambda my_list: [x*2 for x in my_list]
repl = lambda old_t,new_t,my_list: [x if x != old_t else new_t for x in my_list]
print repl("cow","mouse",["cow","rat","monkey","elephant","cow"])
print doubles([1,2,3,4,'d'])