I am learning Python and something related to print
confused me. Not sure if someone asked the same question already:
>>> x = 1
>>> x, y = x + 2, print(x)
1
I understand that output 1
is the side effect of Python's print
function. But why doesn't it print 3
? I was expecting 3
because x
is updated in the second line? I was thinking it is equivalent to (apparently, wrong):
>>> x = 1
>>> x = x + 2
>>> x
3
>>> y = print(x)
3
I would like to understand the logic behind this print
function. Why doesn't it print the updated x
value?
I am new to the programming world, so any insight is highly appreciated!
Everything on the right-hand side is evaluated first. You can use the python byte-code dissasembler to see what is happening:
>>> import dis
>>> dis.dis('x, y = x + 2, print(x)')
1 0 LOAD_NAME 0 (x)
2 LOAD_CONST 0 (2)
4 BINARY_ADD
6 LOAD_NAME 1 (print)
8 LOAD_NAME 0 (x)
10 CALL_FUNCTION 1
12 ROT_TWO
14 STORE_NAME 0 (x)
16 STORE_NAME 2 (y)
18 LOAD_CONST 1 (None)
20 RETURN_VALUE
>>>
Note, x + 2
and print(x)
are evaluated first . The BINARY_ADD and CALL_FUNCTION occur before the two STORE_NAME
s.
Note, you can think of this as the equivalent of building a tuple first,
temp = (x + 2, print(x))
and then simply:
x, y = temp
However, note, according to the dissasembler, no actual intermediate tuple is created. The call stack is used to store the intermediate values. This is a compiler optimization. However, the optimization does not work for tuples greater than length 3, so using 4, you'll see an intermediate tuple is create:
>>> dis.dis('foo, bar, baz, bang = bang, baz, bar, foo')
1 0 LOAD_NAME 0 (bang)
2 LOAD_NAME 1 (baz)
4 LOAD_NAME 2 (bar)
6 LOAD_NAME 3 (foo)
8 BUILD_TUPLE 4
10 UNPACK_SEQUENCE 4
12 STORE_NAME 3 (foo)
14 STORE_NAME 2 (bar)
16 STORE_NAME 1 (baz)
18 STORE_NAME 0 (bang)
20 LOAD_CONST 0 (None)
22 RETURN_VALUE
>>>
Note the BUILD_TUPLE
and UNPACK_SEQUENCE
, which is the general way that unpacking works in Python. It's just the compiler optimizes the common cases of two-or-three with the ROT_TWO and ROT_THREE op codes.
Note, since the right-hand side is evaluate first, this allows for the Python swap idiom to work!
x, y = y, x
If this were equivalent to:
x = y
y = x
You would lose the value for x instead of swapping!
>>> x = 1
>>> x, y = x + 2, print(x)
1
print(x)
outputs the value stored in x assigned by you
for printing 3 you need to print(y)
as y stores the value of x+2
Because python processes line by line (meaning after the whole line, process it), so x
haven't updated yet, so that's why it's not working as expected, but if you do ;
(semicolon) it will work, because semicolon ;
is basically a separator of lines too, so basically everything after ;
is taken as a new line, demo:
>>> x=1
>>> x, y = x + 2,0; print(x)
3
>>>
Issue is that y
is gonna be 0:
>>> y
0
>>>
Because i do so, you have to have a value,
But if you care, delete it:
>>> x=1
>>> x, y = x + 2,0; print(x)
3
>>> del y
>>> y
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
y
NameError: name 'y' is not defined
>>>
直到左侧的所有内容都完成处理后,赋值左侧的值才会更新。这就是为什么当您尝试在右侧打印时X尚未为3的原因。
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.