Reassigning variables in python

I have the following code and variables, and I want to find what the variables a , a1 , a2 , b , b1 and b2 mean after the code has been executed.

 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) 

My solution is as follows:

 a = ["z", "a", "b", "c"] a1 = ["a", "b", "c"] a2 = ["a", "b", "c"] b = ["z" "a", "b", "c"] b1 = ["a", "b", "c"] b2 = ["a", "b", "c"] 

But the actual solution:

 a = ["z", "a", "b", "c"] a1 = ["z", "a", "b", "c"] a2 = ["a", "b", "c"] b = ["a", "b", "c"] b1 = ["a", "b", "c"] b2 = ["a", "b", "c"] 

Can someone pass me on my mistake?

+6
source share
1 answer

Well, you can think of variables in Python as links. When you do:

 a1 = a 

Both a1 and a are references to the same object, so if you change the object that a points to, you will see changes in a1 , because - surprise - this is the same object (and the list.insert method changes the list in place).

But when you do:

 a2 = a[:] 

Then a2 is a new instance of list , and when you change a you do not change a2 .

The result of the + operator for lists is a new list, so when you do:

 b = ['z'] + b 

You assign a new list b instead of mutating b in place, as you would with b.insert('z') . Now b points to a new object, and b1 still points to the old value of b .

But the scope can be even more complex: you can see the scope of the function, but if you assign a variable inside the function, it will not change the variable with the same name in the scope (either global or in -in), it will create a variable with this name in the local area. That's why b was not changed - well, not really, passing parameters to Python is an assignment operation, so b already a local variable when there is a parameter called b -, but trying to change a variable defined in the surrounding area leads to a similar problem . By the way, it is bad practice to rely on variables from the covering area if they are not constants at the module level (traditionally they are called in the style of ALL_UPPERCASE, and you should not mutate them). If you need a value inside the function, pass it as a parameter, and you want to change the value of the variable in the enclosing area, return the value and assign the return value there:

 def do_something(a, b): a.insert(0, "z") # mutates a in-place return ["z"] + b b = do_something(a, b) 
+6
source

Source: https://habr.com/ru/post/985724/


All Articles