Each of next() and list() iterates over generator with mutable object differently

前端 未结 3 892
孤城傲影
孤城傲影 2021-01-25 10:27
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         


        
3条回答
  •  爱一瞬间的悲伤
    2021-01-25 11:03

    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.

提交回复
热议问题