Why am I only getting one item from list - python

I am trying to get shared letters from a string compared to a list of letters. I only return the last letter of l that shares with w . I want all the shared letters instead.
def f(w,l):
common = []
for i in w:
if in i in l:
return common.append(i)

As soon as i is in l your code returns, which immediately exits your function. instead do this:
def f(w,l):
common = []
for i in w:
if i in l:
common.append(i) # no return needed so it will collect all
return common
Make sure you return common at the end your function so you get all the values stored in common.

try this:
def f(w,l):
common = []
for i in w:
if i in l:
common.append(i)
return common

The problem is that the .append method of a list returns None. You were returning from the function the first time you did .append, so you were always going to return None from the function.
I think that what you are really looking for is a list comprehension:
def f(w,l):
return [i for i in w if i in l]
As others have pointed out, you might want to choose more descriptive variable names.

Related

python build a list recursively

Let's say I have a string
S = "qwertyu"
And I want to build a list using recursion so the list looks like
L = [u, y, t, r, e, w, q]
I tried to write code like this:
def rec (S):
if len(S) > 0:
return [S[-1]].append(rec(S[0:-1]))
Ideally I want to append the last element of a shrinking string until it reaches 0
but all I got as an output is None
I know I'm not doing it right, and I have absolutely no idea what to return when the length of S reaches 0, please show me how I can make this work
(sorry the answer has to use recursion, otherwise it won't bother me)
Thank you very much!!!
There are many simpler ways than using recursion, but here's one recursive way to do it:
def rec (S):
if not S:
return []
else:
temp = list(S[-1])
temp.extend(rec(S[:-1]))
return temp
EDIT:
Notice that the base case ensures that function also works with an empty string. I had to use temp, because you cannot return list(S[-1]).extend(rec(S[:-1])) due to it being a NoneType (it's a method call rather than an object). For the same reason you cannot assign to a variable (hence the two separate lines with temp). A workaround would be to use + to concatenate the two lists, like suggested in Aryerez's answer (however, I'd suggest against his advice to try to impress people with convoluted one liners):
def rec (S):
if not S:
return []
else:
return list(S[-1]) + rec(S[:-1])
In fact using + could be more efficient (although the improvement would most likely be negligible), see answers to this SO question for more details.
This is the simplest solution:
def rec(S):
if len(S) == 1:
return S
return S[-1] + rec(S[:-1])
Or in one-line, if you really want to impress someone :)
def rec(S):
return S if len(S) == 1 else S[-1] + rec(S[:-1])
Since append mutates the list, this is a bit difficult to express recursively. One way you could do this is by using a separate inner function that passes on the current L to the next recursive call.
def rec(S):
def go(S, L):
if len(S) > 0:
L.append(S[-1])
return go(S[0:-1], L)
else:
return L
return go(S, [])
L = [i for i in S[::-1]]
It should work.

Wide Search alike function that is supposed to give two lists back, one with visited items and one without

In the following Function I tried to simulate an wide search alike function.
First Function 'Hello' by giving and search name = V, is supposed to give you all the tuple partners that it has in a list.
Second Function is supposed to have two lists, first for already visited and the ones who are still in a list i.e. que.
With two for loops I went through newly generated list by the word given in, so that I can use those words to generate further tuple partners, that aren't in besucht list. After the usage has been done the item will be deleted from the 'Liste' and appended to besucht.
Question: It doesn't work as I intended and I don't understand why
V = {'CGN', 'FRA','KEL','MUC','PAD','SFX','STR','TXL'}
E = {('SFX','TXL'),('FRA','CGN'),('FRA','MUC'),('FRA','STR'),('CGN','FRA'),('STR','FRA'),('TXL','SFX'),('CGN','PAD'),('PAD','KEL'),('MUC','KEL'),('KEL','STR') }
S = {('A','B'),('A','B')}
def Hallo(V,E):
Total = []
Que = []
for i in E:
for j in i:
if j == V:
Total.append(i)
for i in Total:
for a in i:
if a != V:
if a not in Que:
Que.append(a)
return Que
def Durchsuchen(V,E):
besucht = []
Liste = []
Liste.append(Hallo(V,E))
besucht.append(V)
while len(Liste) !=0
for i in Liste:
if i not in besucht:
besucht.append(i)
Liste.remove(i)
Liste.append(Hallo(i,E))
print Liste
print besucht
print Durchsuchen('FRA',E)
What is supposed to do? It's supposed to give you all the possibilities i.e if you give in 'FRA' it will generate [MUC, STR, CGN] since MUC and etc is within this list this should also give you KEL for example. I.E all the possible options that are out there.
Well your problem is that you use remove() on a list inside a loop that iterates through it - which should never be done. This changes the logic that the loop relies on and causes your unexpected results.
The first function works just fine so I'd suggest you to use it once on your first word 'FRA', and then use it on every word that pairs with it - [MUC, STR, CGN] in your example. Then use the following code on the lists that you got:
newList = []
for ls in listOfLists:
for word in ls:
if word not in newList:
newList.append(word)

function would not change the parameter as wanted

here is my code
def common_words(count_dict, limit):
'''
>>> k = {'you':2, 'made':1, 'me':1}
>>> common_words(k,2)
>>> k
{'you':2}
'''
new_list = list(revert_dictionary(count_dict).items())[::-1]
count_dict = {}
for number,word in new_list:
if len(count_dict) + len(word) <= limit:
for x in word:
count_dict[x] = number
print (count_dict)
def revert_dictionary(dictionary):
'''
>>> revert_dictionary({'sb':1, 'QAQ':2, 'CCC':2})
{1: ['sb'], 2: ['CCC', 'QAQ']}
'''
reverted = {}
for key,value in dictionary.items():
reverted[value] = reverted.get(value,[]) + [key]
return reverted
count_dict = {'you':2, 'made':1, 'me':1}
common_words(count_dict,2)
print (count_dict)
what i expected is to have the count_dict variable to change to {'you':2}.
It did work fine in the function's print statement, but not outside the function..
The problem, as others have already written, is that your function assigns a new empty dictionary to count_dict:
count_dict = {}
When you do this you modify the local variable count_dict, but the variable with the same name in the main part of your program continues to point to the original dictionary.
You should understand that you are allowed to modify the dictionary you passed in the function argument; just don't replace it with a new dictionary. To get your code to work without modifying anything else, you can instead delete all elements of the existing dictionary:
count_dict.clear()
This modifies the dictionary that was passed to the function, deleting all its elements-- which is what you intended. That said, if you are performing a new calculation it's usually a better idea to create a new dictionary in your function, and return it with return.
As already mentioned, the problem is that with count_dict = {} you are not changing the passed in dictionary, but you create a new one, and all subsequent changes are done on that new dictionary. The classical approach would be to just return the new dict, but it seems like you can't do that.
Alternatively, instead of adding the values to a new dictionary, you could reverse your condition and delete values from the existing dictionary. You can't use len(count_dict) in the condition, though, and have to use another variable to keep track of the elements already "added" to (or rather, not removed from) the dictionary.
def common_words(count_dict, limit):
new_list = list(revert_dictionary(count_dict).items())[::-1]
count = 0
for number,word in new_list:
if count + len(word) > limit:
for x in word:
del count_dict[x]
else:
count += len(word)
Also note that the dict returned from revert_dictionary does not have a particular order, so the line new_list = list(revert_dictionary(count_dict).items())[::-1] is not guaranteed to give you the items in any particular order, as well. You might want to add sorted here and sort by the count, but I'm not sure if you actually want that.
new_list = sorted(revert_dictionary(count_dict).items(), reverse=True)
just write
return count_dict
below
print count_dict
in function common_words()
and change
common_words(count_dict,2)
to
count_dict=common_words(count_dict,2)
So basically you need to return value from function and store that in your variable. When you are calling function and give it a parameter. It sends its copy to that function not variable itself.

Python string function that removes one duplicate pair from multiple duplicates

I'm looking for a string function that removes one duplicate pair from multiple duplicates.
What i'd like the function to do:
input = ['a','a','a','b','b','c','d','d','d','d']
output = ['a','c']
heres what I have so far:
def double(lijst):
"""
returns all duplicates in the list as a set
"""
res = set()
zien = set()
for x in lijst:
if x in zien or zien.add(x):
res.add(x)
return(res)
def main():
list_1 = ['a','a','a','b','b','c']
list_2 = set(list_1)
print(list_2 - double(list_1))
main()
The problem being that it removes all duplicates, and doesn't leave the 'a'. Any ideas how to approach this problem?
For those interested why I need this; I want to track when a levehnstein function is processing vowel steps, if a vowel is being inserted or deleted I want to assign a different value to 'that step' (first I need to tract if a vowel has passed on either side of the matrix before the current step though) hence I need to remove duplicate pairs from a vowel list (as explained in the input output example).
These solves your problem. Take a look.
lsit = ['a','a','a','b','b','c']
for i in lsit:
temp = lsit.count(i)
if temp%2==0:
for x in range(temp):
lsit.remove(i)
else:
for x in range(temp-1):
lsit.remove(i)
print lsit
Output:
['a','c']
Just iterate through the list. If an element does not exist in the result, add it to the set. Or if there does already have one in the set, cancel out those two element.
The code is simple:
def double(l):
"""
returns all duplicates in the list as a set
"""
res = set()
for x in l:
if x in res:
res.remove(x)
else:
res.add(x)
return res
input = ['a','a','a','b','b','c','d','d','d','d']
print double(input)

Summing objects in recursive python function

I need to sum objects (strings, ints, etc.) in one function (don't create other function, it can be done within one). It should work this way: When given my_sum([[['s'],'ta'],['c',['k']]]), it should return 'stack'.
I came up with this:
def my_sum(array):
if not array: #empty array
return None
else:
for item in array:
if type(item) == list:
my_sum(item)
else:
print(item)
It of course is not doing what it should be, I was just playing around with it trying to come up with something. This code above returns this:
s
ta
c
k
I think I am not that far from result as I have what I need, but here is the problem how can I sum up those items ? I can't write result = '' anywhere in the function and then return it, because it would be deleting every time there would be recursion call. Also I don't want global variables (if anyone would think of that). Maybe I am just being stupid and can't see that it is one simple thing, pardon me if it is so.
Thank you for every answer!
The common accumulating pattern is:
result = <init value>
for item in argument:
result = result <operator> item
return result
(this can be written more concisely, but that's not the point for now).
Applied to your problem:
def my_sum(items):
result = ''
for item in items:
if type(item) == list:
result += my_sum(item)
else:
result += item
return result
Note that type(x) == y is frowned upon in Python, isinstance is considered better style.
Homework: extend the function so that it works for these arguments too:
print my_sum([[['s'],'ta'],('c',('k')), {('over'), ('flow')}])

Categories

Resources