Multiple assignment and evaluation order in Python

前端 未结 10 1906
醉酒成梦
醉酒成梦 2020-11-22 01:41

What is the difference between the following Python expressions:

# First:

x,y = y,x+y

# Second:

x = y
y = x+y

First gives diffe

相关标签:
10条回答
  • 2020-11-22 02:20
    a, b = 0, 1
    while b < 10:
        print(b)
        a, b = b, a+b
    

    Output

    1
    1
    2
    3
    5
    8
    

    the variables a and b simultaneously get the new values 0 and 1, the same a, b = b, a+b, a and b are assigned simultaneously.

    0 讨论(0)
  • 2020-11-22 02:24

    In an assignment statement, the right-hand side is always evaluated fully before doing the actual setting of variables. So,

    x, y = y, x + y
    

    evaluates y (let's call the result ham), evaluates x + y (call that spam), then sets x to ham and y to spam. I.e., it's like

    ham = y
    spam = x + y
    x = ham
    y = spam
    

    By contrast,

    x = y
    y = x + y
    

    sets x to y, then sets y to x (which == y) plus y, so it's equivalent to

    x = y
    y = y + y
    
    0 讨论(0)
  • 2020-11-22 02:25

    Let's grok the difference.

    x, y = y, x + y It's x tuple xssignment, mexns (x, y) = (y, x + y), just like (x, y) = (y, x)

    Stxrt from x quick example:

    x, y = 0, 1
    #equivxlent to
    (x, y) = (0, 1)
    #implement xs
    x = 0
    y = 1
    

    When comes to (x, y) = (y, x + y) ExFP, have x try directly

    x, y = 0, 1
    x = y #x=y=1
    y = x + y #y=1+1
    #output
    In [87]: x
    Out[87]: 1
    In [88]: y
    Out[88]: 2
    

    However,

    In [93]: x, y = y, x+y
    In [94]: x
    Out[94]: 3
    In [95]: y
    Out[95]: 5
    

    The result is different from the first try.

    Thx's because Python firstly evaluates the right-hand x+y So it equivxlent to:

    old_x = x
    old_y = y
    c = old_x + old_y
    x = old_y
    y = c
    

    In summary, x, y = y, x+y means,
    x exchanges to get old_value of y,
    y exchanges to get the sum of old value x and old value y,

    0 讨论(0)
  • 2020-11-22 02:26

    An observation regarding the left-hand side as well: the order of assignments is guaranteed to be the order of their appearance, in other words:

    a, b = c, d
    

    is equivalent functionally to precisely (besides t creation):

    t = (c, d)
    a = t[0] # done before 'b' assignment
    b = t[1] # done after 'a' assignment
    

    This matters in cases like object attribute assignment, e.g.:

    class dummy:
        def __init__(self): self.x = 0
    
    a = dummy(); a_save = a
    a.x, a = 5, dummy()
    print(a_save.x, a.x) # prints "5 0" because above is equivalent to "a = dummy(); a_save = a; t = (5, dummy()); a.x = t[0]; a = t[1]"
    
    a = dummy(); a_save = a
    a, a.x = dummy(), 5
    print(a_save.x, a.x) # prints "0 5" because above is equivalent to "a = dummy(); a_save = a; t = (dummy(), 5); a = t[0]; a.x = t[1]"
    

    This also implies that you can do things like object creation and access using one-liners, e.g.:

    class dummy:
        def __init__(self): self.x = 0
    # Create a = dummy() and assign 5 to a.x
    a, a.x = dummy(), 5
    
    0 讨论(0)
提交回复
热议问题