Python中的多重赋值和求值顺序

Python中的多重赋值和求值顺序,python,variable-assignment,assignment-operator,multiple-assignment,Python,Variable Assignment,Assignment Operator,Multiple Assignment,以下Python表达式之间有什么区别: # First: x,y = y,x+y # Second: x = y y = x+y 第一个给出的结果与第二个不同 e、 g 第一: 第二: y第一个是3,第二个是4在第二种情况下,您将x+y分配给x 在第一种情况下,第二个结果(x+y)被分配给y 这就是为什么会得到不同的结果 编辑后 这是因为,在声明中 x,y = y,x+y x = y y = x + y 对右成员处的所有变量进行求值,然后将其存储在左成员中。因此,第一个处理右成员,第

以下Python表达式之间有什么区别:

# First:

x,y = y,x+y

# Second:

x = y
y = x+y
第一个给出的结果与第二个不同

e、 g

第一:

第二:


y第一个是3,第二个是4在第二种情况下,您将
x+y
分配给
x

在第一种情况下,第二个结果(
x+y
)被分配给
y

这就是为什么会得到不同的结果

编辑后

这是因为,在声明中

x,y = y,x+y
x = y
y = x + y
对右成员处的所有变量进行求值,然后将其存储在左成员中。因此,第一个处理右成员,第二个处理左成员

在第二次发言中

x,y = y,x+y
x = y
y = x + y

您首先计算了
y
,并将其分配给
x
;这样,
x+y
的和等于
y+y
的和,而不是
x+x
的和,这是第一种情况。

第一种是元组式赋值:

x,y = y,x+y
其中,
x
是元组的第一个元素,
y
是第二个元素,因此您要做的是:

x = y
y = x+y
当第二个正在做一个直接赋值时:

x=y
x=x+y
第一句话:

  • 创建一个临时元组,值为
    y,x+y
  • 分配给另一个临时元组
  • 将元组提取到变量
    x
    y
  • 第二条语句实际上是两个表达式,没有元组用法

    令人惊讶的是,第一个表达实际上是:

    temp=x
    x=y
    y=temp+y
    

    您可以了解有关“.”中逗号用法的更多信息。

    在赋值语句中,在实际设置变量之前,始终对右侧进行完全求值。所以

    x, y = y, x + y
    
    计算
    y
    (我们将结果称为
    ham
    ),计算
    x+y
    (称为
    spam
    ),然后将
    x
    设置为
    ham
    ,将
    y
    设置为
    spam
    。也就是说,就像

    ham = y
    spam = x + y
    x = ham
    y = spam
    
    相比之下

    x = y
    y = x + y
    
    x
    设置为
    y
    ,然后将
    y
    设置为
    x
    (其中
    ==y
    )加上
    y
    ,因此它相当于

    x = y
    y = y + y
    

    文件中标题为:

    。。。评估作业时,将评估右侧 在左手边之前


    变量
    a
    b
    同时获得新值
    0
    1
    ,相同的
    a、b=b、a+b
    a
    b
    同时赋值

    让我们探索一下不同之处

    x,y=y,x+y
    它是x元组xsignment,mexns
    (x,y)=(y,x+y)
    ,就像
    (x,y)=(y,x)

    来自x的Stxrt快速示例:

    x, y = 0, 1
    #equivxlent to
    (x, y) = (0, 1)
    #implement xs
    x = 0
    y = 1
    
    当涉及到
    (x,y)=(y,x+y)
    ExFP,让x直接尝试

    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
    
    但是,

    In [93]: x, y = y, x+y
    In [94]: x
    Out[94]: 3
    In [95]: y
    Out[95]: 5
    
    结果与第一次尝试不同

    Thx是因为Python首先计算右边的
    x+y
    因此,它相当于:

    old_x = x
    old_y = y
    c = old_x + old_y
    x = old_y
    y = c
    
    总之,
    x,y=y,x+y
    表示,
    x
    交换以获取
    y
    的旧值,

    y
    交换旧值
    x
    和旧值
    y

    我最近开始使用Python,这个“特性”让我感到困惑。虽然给出了很多答案,但我还是会发布我的理解

    如果我想交换两个变量的值,在JavaScipt中,我将执行以下操作:

    var a=0;
    var b=1;
    var-temp=a;
    a=b;
    b=温度;
    
    我需要第三个变量来临时保存其中一个值。一个非常简单的交换是行不通的,因为两个变量的值都是一样的

    var a=0;
    var b=1;
    a=b;//b=1=>a=1
    b=a;//a=1=>b=1
    
    想象一下,有两个不同的(红色和蓝色)桶,里面分别有两种不同的液体(水和油)。现在,尝试交换桶/液体(蓝色的水和红色桶中的油)。除非你有多余的桶,否则你做不到

    Python以“更干净”的方式/解决方案处理此问题:


    我想,这种方式Python会自动创建“temp”变量,我们不必担心它们。

    其他答案已经解释了它的工作原理,但我想添加一个真正具体的示例

    x = 1
    y = 2
    x, y = y, x+y
    
    在最后一行中,首先对名称进行如下解引用:

    x, y = 2, 1+2
    
    然后计算表达式:

    x, y = 2, 3
    
    然后展开元组,然后进行赋值,相当于:

    x = 2; y = 3
    

    关于左手边的观察:作业的顺序保证为其出现的顺序,换句话说:

    a, b = c, d
    
    在功能上与精确等效(除t创建外):

    这在对象属性分配等情况下很重要,例如:

    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]"
    
    这也意味着您可以使用一行程序创建和访问对象,例如:

    class dummy:
        def __init__(self): self.x = 0
    # Create a = dummy() and assign 5 to a.x
    a, a.x = dummy(), 5
    

    对于新手,我遇到了这个例子,可以帮助解释这一点:

    # Fibonacci series:
    # the sum of two elements defines the next
    a, b = 0, 1
    while a < 10:
        print(a)
        a, b = b, a+b
    
    斐波那契级数: #两个元素之和定义下一个元素 a、 b=0,1 而a<10: 印刷品(a) a、 b=b,a+b 对于多重赋值,将初始值设置为a=0,b=1。
    在while循环中,两个元素都被分配了新值(因此称为“多个”分配)。将其视为(a,b)=(b,a+b)。在循环的每次迭代中,a=b,b=a+b。这一点仍然存在,但与代码库中的类似语法相关
    x,y=y,x+y
    (x,y)=y,x+y
    相同,因此不需要括号。这听起来对吗?@jxramos是的,括号是不必要的,但这更多的是关于元组的问题。就像链接提到的“在任何赋值之前对右侧的所有表达式求值”。谢谢你的澄清。
    t = (c, d)
    a = t[0] # done before 'b' assignment
    b = t[1] # done after 'a' assignment
    
    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]"
    
    class dummy:
        def __init__(self): self.x = 0
    # Create a = dummy() and assign 5 to a.x
    a, a.x = dummy(), 5
    
    # Fibonacci series:
    # the sum of two elements defines the next
    a, b = 0, 1
    while a < 10:
        print(a)
        a, b = b, a+b