简体   繁体   中英

Why do lists in python behave this way?

If I have the following function and code:

def do_something(a, b):
    a.insert(0, ’z’)
    b = [’z’] + b
a = [’a’, ’b’, ’c’]
a1 = a
a2 = a[:]
b = [’a’, ’b’, ’c’]
b1 = b
b2 = b[:]
do_something(a, b)

Why does print(a) yield ['z','a','b','c'] , but printing b still only prints ['a','b','c'] ?

In the function I made b = b + ['z'] so shouldn't z be in the list as well?

Also why does printing a[:] not print the new list ['z','a','b','c'] and prints the old list ['a','b','c'] instead?

Because in do_something you are modifying the list that has the label a but you are creating a new list and reassigning that to label b , not modifying the list with the label b

That means the list outside do_something for a has been changed, but not the b one, because you're just coincidentally using the same names inside the func, you could also do the same thing with the func with different names like:

def do_something(x, y):
    x.insert(0, ’z’)
    y = [’z’] + y

and your prints on the outside would still behave as you report, because the labels for the objects inside the function and outside are not related, in your example they just happen to be the same.

From https://docs.python.org/2/library/copy.html

Shallow copies of dictionaries can be made using dict.copy(), and of lists by 
assigning a slice of the entire list, for example, copied_list = original_list[:].

OK

def do_something(a, b):
    a.insert(0, 'z') #this is still referencing a when executed. a changes.
    b = ['z'] + b #This is a shallow copy in which the b in this function, is now [’a’, ’b’, ’c’, 'z']. 

Although the above is true, the b you are thinking of that has the 'z' is not the same b that will be printed at the "end" of the program. The b printed on the first line though, is the b in the function def_something().

Code:

def do_something(a, b):
    a.insert(0, 'z') #any changes made to this a changes the a that was passed in the function.
    b = ['z'] + b #This b is do_something() local only. LEGB scope: E. Link below about LEGB. 
print("a b in function: ", a, "|", b)
a = ['a', 'b', 'c']
a1 = a
a2 = a[:] #This is never touched following the rest of your code.
b = ['a', 'b', 'c']
b1 = b
b2 = b[:] #This is never touched following the rest of your code.
print("a b before function: ", a, "|", b)
do_something(a, b)
print("a b after function: ", a, "|", b) #This b is same thing it was after assignment.  

Output:

a b before function:  ['a', 'b', 'c'] | ['a', 'b', 'c']
a b in function:  ['z', 'a', 'b', 'c'] | ['z', 'a', 'b', 'c']
a b after function:  ['z', 'a', 'b', 'c'] | ['a', 'b', 'c']

More info on LEGB .

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