1

I was playing around with a block of code during which I stumbled upon some unexpected behaviour of Python.

I defined a list as follows:

a = [1, 2, 3]

Made another list with a loop:

res = (item for item in a if a.count(item) > 0)
print(list(res)) # [1, 2, 3] -- as expected -- Consider this is line 1

Then later I changed the initial value of first list:

a = [7, 2, 9]

I was expecting no change in res as the changes I made to a were after res was created, but to my surprise, the value of res was changed.

print(list(res)) # prints [] -- Consider this as line 2

What's more shocking is that the result of print depends on print statement on line 1, if I comment out print statement at line1 then line 2 prints [2]

Can someone please explain me what's going on here?

Yudhishthir Singh
  • 2,941
  • 2
  • 23
  • 42

2 Answers2

4

res = (item for item in a if a.count(x) > 0) creates a generator that is exhausted by calling list(res).

When you call the next list(res) it returns empty list - []

consider creating a list first, for example res = [item for item in a if a.count(x) > 0].

Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
  • Hey @andrej, It would be really kind of you if you could give my answer a read and post a comment on that if you think its right or wrong. – Yudhishthir Singh May 29 '20 at 22:38
  • @YudhishthirSingh Yes, your answer is OK - the generator can be iterated over only once. There's more info about it for example here: https://stackoverflow.com/questions/47789/generator-expressions-vs-list-comprehension – Andrej Kesely May 29 '20 at 22:44
0

Okay, I think I get it, I was not creating another list with that loop and I was creating something called generator.

Which can be converted to list only once, that is why it prints [] if I give print statement at line 1.

And it modifies itself according to value of a until it is exhausted.

Yudhishthir Singh
  • 2,941
  • 2
  • 23
  • 42