def generator(dct):
for i in range(3):
dct[\'a\'] = i
yield dct
g = generator({\'a\': None})
next(g) # -> {\'a\': 0}
next(g) # -> {\'a\': 1}
n
Your generator()
generator always yields the same dict
object, just with modifications made to it between calls. If you were to, say, change the first next(g)
to x = next(g)
and then inspect x
before and after calling next(g)
again, you would see the value of x
change across calls, because generator()
is always modifying & yielding the same dict
object.
You are looking at intermediate print results. You are modifying a single dictionary, and sharing references to it. You can see the intermediary steps, but that doesn't mean the result is different.
Store a reference to the object returned from next()
and they'll all be the same:
g = generator({'a': None})
first = next(g)
second = next(g)
third = next(g)
print(first, second, third) # -> {'a': 2} {'a': 2} {'a': 2}
first
, second
and third
are all references to the same object:
>>> first is second and second is third
True
You'd see the same thing if you did this in a regular for
loop:
>>> results = []
>>> d = {'a': None}
>>> for i in range(3):
... d['a'] = i
... print(d)
... results.append(d)
...
{'a': 0}
{'a': 1}
{'a': 2}
>>> print(results)
[{'a': 2}, {'a': 2}, {'a': 2}]
>>> all(d is elem for elem in results) # all references in results are the same object
True
The loop prints the dictionary object as it changes each step. The results
list contains 3 references to the same object, and each shows the same state once printed at the end.
They iterate over the iterator identically, but you're checking in at different points. Because dict
s are mutable, and you always yield
the same dict
, you should expect everything you yield to be identical. In your first example, you are looking at the dict
as it is changing. Instead consider
g = generator({'a': None})
a = next(g)
b = next(g)
c = next(g)
print(a, b, c)
# {'a': 2} {'a': 2} {'a': 2}