1

I tried to create a simple function to remove duplicates from the list.

x = [7, 7, 5, 6, 8, 9, 9, 0]
for n, i in enumerate(x):
  if i in x[n + 1:]:
    x.remove(i)
print(x)

Output:

[7, 5, 6, 8, 9, 0]

This code works fine as far as I know.

But when I'm trying to convert it in comprehension list form, I'm getting wrong output:

def unique_list(lst):
  return [lst.remove(i) for n, i in enumerate(lst) if i in lst[n + 1:]]

x = [7, 7, 5, 6, 8, 9, 9, 0]
print(unique_list(x))

Output:

[None, None]

So, the question is - why the output is different?

Quanti Monati
  • 769
  • 1
  • 11
  • 35
  • You're modifying list while you're iterating over it in both examples which is really bad practice. This code will work: `x1 = [i for i, j in zip(x, x[1:] + [None]) if i != j]` – Olvin Roght Jun 10 '20 at 11:59
  • Does this answer your question? [How to remove items from a list while iterating?](https://stackoverflow.com/questions/1207406/how-to-remove-items-from-a-list-while-iterating) – ojdo Jun 10 '20 at 12:00
  • @OlvinRoght in real world coding I'm not going that way. My interest in this case is theoretical. – Quanti Monati Jun 10 '20 at 12:02
  • Voting to close, see https://stackoverflow.com/a/1207461/2375855 . And your example function suffers from being very similar to simply `list(set(x))`. (Only similar, as this does not preserve order.) – ojdo Jun 10 '20 at 12:02
  • You are returning the output of .remove(), which is always None. The remove method changes the list, its not returning a changed list – Manuel Jun 10 '20 at 12:04
  • @ojdo I'm trying to understand what's the difference between this to examples sees Python interpreter and why the output is different. – Quanti Monati Jun 10 '20 at 12:05
  • 2
    @QuantiMonati, difference is in logic. Examples aren't equal. In first example you're removing elements from list and return this list, in second example you're creating list which contains return of `list.remove()` which will alway be `None`. – Olvin Roght Jun 10 '20 at 12:08

2 Answers2

3
a = [1, 2, 3]
deleted = a.remove(1)
print(deleted)
# returns None
print(a)
# returns [2, 3]

.remove() changes the list in place and returns None

Manuel
  • 546
  • 1
  • 5
  • 17
2

Your two ways of writing the functionality of set(x) are not identical. While the first is using a side-effect of x.remove(..) to "return" your modified list in place, the second form returns a newly created list.

The elements of that list are formed by what is returned by the expression lst.remove(i), which is None as Manuel already has pointed out in their answer.

You receive [None, None] because your code calls lst.remove 2 times. So your function unique_list could be called count_duplicates, just with a peculiar output format (with the length of a list of None encoding the result instead of a straightforward int).

ojdo
  • 8,280
  • 5
  • 37
  • 60