简体   繁体   中英

Python: why are lists defined inside while loops recycled but not variables that are assigned lists inside same loop?

Still new, I searched google but I didn't really find an explanation so thank you in advance. When writing Python, why is is that during a while loop, a variable that is assigned a list outside of the while loop can be modified and retain it's modifications with each iteration, but a variable that is assigned a list during the loop will revert back to it's original assignment with each iteration? Here is an example code:

x = [1,1,1]

while True:
    a = [1,1,1]
    b = x
    a.append(1)
    b.append(2)
    print(a)
    print(b)

why does variable a stay the same, while variable b can be appended with each iteration and maintain its modifications? Thanks.

Since b and x are references to the same list object, your code is equivalent to

x = [1,1,1]

while True:
    a = [1,1,1]
    a.append(1)
    x.append(2)
    print(a)
    print(x)

In each iteration of the loop, the list referenced by x gains another element. a is a reference to a new 3-element list in each iteration, though, so it never gets bigger than 4 elements before being discarded. It's easier to see if you unroll the (original) loop:

x = [1,1,1]

a = [1,1,1]  # new list
b = x        # reference to old list
a.append(1)
b.append(2)
print(a)
print(b)

a = [1,1,1]  # new list
b = x        # reference to old list
a.append(1)
b.append(2)
print(a)
print(b)

...

You can also sprinkle in a few calls to print(id(a)) and print(id(b)) to see that id(b) never changes, while id(a) changes in each iteration. (Due to how the garbage collector works, id(a) will probably oscillate back and forth between 2 distinct values, though.)

It's because a is redefined at each iteration, while b isn't. When you write b = x , you only link b to x, and modifying b in your loop is in fact changing only the list that it refers to, the same list that x refers to which isn't redefined at each iteration (unlike a ).

This is a classic case of Shallow Copy vs Deep Copy.

This code below will give you results as expected by you.

import copy
x = [1,1,1]

while True:
    a = [1,1,1]
    b = copy.deepcopy(x)
    a.append(1)
    b.append(2)
    print(a)
    print(b)

Assignment statements by default do not copy objects, they create bindings between a target and an object.

Shallow copy is by default. To completely copy the values, we need deepcopy as shown in the above code

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM