The Maniero's answer clearly explained that the problem with the implemented logic was to change the structure being iterated and its examples could not be more didactic, so I would just like to add a summarized form of solutions:
def remove_duplicados(l1, l2):
return [i for i in l1 if i not in l2]
So, the function returns a new list with elements of l1
that do not belong to l2
.
l1 = [1, 2, 3, 4]
l2 = [1, 2, 5, 6]
print(remove_duplicados(l1, l2)) # [3, 4]
See working at Repl.it | Ideone
Some advantages in this solution are:
When you replace brackets with brackets in return, the function returns a generator, which can save memory;
It is not necessary to create copies of the input lists;
The entry lists remain intact (may be useful in some cases);
Readable solution;
Feedback :
In the memory economy mentioned in item 1, we have two observations: a) the economy of gives by the fact that, when replacing the brackets by parentheses, the return of the function ceases to be a list and becomes a list generator; In this way, the final list stored in memory is not available, since the generator calculates each item according to its use ( lazy
calculation or call-by-need ). b) the references to the input objects remain the same in of the generator, not creating a copy of them; that is, even after the generator is set, any change in the input lists will affect the generator.
With brackets, the return is a new list:
x = [1, 2, 3, 4, 5]
y = [2, 4]
def remove_duplicados(l1, l2):
return [i for i in l1 if i not in l2]
z = remove_duplicados(x, y)
print(type(z)) # <class 'list'>
# Apenas para demonstrar a saída:
print(list(z)) # [1, 3, 5]
See working at Repl.it | Ideone | GitHub GIST
With parentheses, return is a generator:
x = [1, 2, 3, 4, 5]
y = [2, 4]
def remove_duplicados(l1, l2):
return (i for i in l1 if i not in l2)
z = remove_duplicados(x, y)
print(type(z)) # <class 'generator'>
# Apenas para demonstrar a saída:
print(list(z)) # [1, 3, 5]
See working at Repl.it | Ideone | GitHub GIST
As the list references remain the same, any changes to them will be reflected in the generator result:
x = [1, 2, 3, 4, 5]
y = [2, 4]
def remove_duplicados(l1, l2):
return (i for i in l1 if i not in l2)
z = remove_duplicados(x, y)
# Alteração em y:
y.append(3)
print(type(z)) # <class 'generator'>
# Saída de z modificada devido alteração em y:
print(list(z)) # [1, 5]
See working at Repl.it | Ideone | GitHub GIST
Items 2 and 3 are complementary because if the problem requires that the list of entries should remain intact after the function is executed, using list comprehension or the generator does not need to create a copy in memory of the list to modify it; the return will be a new list with just the items you want.
Item 4 is quite subjective, but I particularly think the solution is much more readable:
def remove_duplicates(source, reference):
return (item for item in source if item not in reference)