解释整数x的单行赋值,list [x]中的item和引用变量间的单行赋值之间的区别

时间:2018-02-23 05:55:28

标签: python list variable-assignment

我相信我在试图弄清楚如何正确地提出问题时回答了我自己的问题,但由于我发现Python's documentation中的答案相当不透明,我以为我还是会发帖子这里的问题。

在尝试理解Python中单行赋值的规则时,我遇到了一些与通常的陈述相矛盾的例子,即#34;多行变量的单行赋值都是一次性发生的#34;。

a = 0 # variable 'a' must be assigned first

a, b = 1, a # a, b :: 1, 0

x = [2, 3, 4, 5, 6]

i, x[i] = 4, 99 # i, x[4] :: 4, 99; variable 'i' does not need to have been previously assigned

c = 8 # variable 'c' must be assigned first

c, d = 9, print(c) # c, d :: 9, None; prints 8

我的困惑与Python首先重新分配'i'(即列表索引)这一事实有关,然后将99分配给列表'x'的索引4。

虽然Python的文档直接解决了这个问题,但

  

虽然赋值的定义意味着它们之间存在重叠   左手侧和右手侧是'同时'(for   例如a,b = b,交换两个变量),重叠在   分配给变量的集合有时从左到右发生   导致混乱。

我不明白"在分配给变量的集合中的重叠"。

我现在看到解析器将检查给定List的索引值是否已重新分配,然后才将新值分配给列表的索引。

说明:

事实证明,在这种情况下,'i'在用作变量索引之前不需要先分配,而对于'a'则需要(否则,Python)会抛出错误。)

对于那些好奇的人来说,PythonTutor visualization。不幸的是,因为它在一行中执行赋值(,因为它应该),所以人们无法真正看到Python如何解释该语句。

如果用户之前已将i分配给整数,并且打算将该前一个整数用作索引而不是新值,则执行的不透明性会更加复杂。

顺便说一句,这是我第一次提出问题,所以我没有必要的声誉来发表我自己的答案。请随时提供任何建设性的建议,告诉我如何改进我可能会提出的任何未来问题,或者我如何更好地为这个社区做出贡献。感谢。

3 个答案:

答案 0 :(得分:0)

也许这是一个英文问题?

  

在分配给变量的集合中重叠 从左到右重叠

因此,LHS是#34;分配给变量的集合"。换句话说,"分配给变量"是将赋值的变量,即LHS。

"在LHS"中重叠表示一个变量引用的对象取决于另一个。在您的示例中,c[i]引用的对象取决于i,因此

i, c[i] = 4, 99

从左到右运行。

然而,在下一次测试中:

c, d = 9, print(c)

由于LHS变量cd不重叠(相互依赖),因此cd的分配是平行的。

答案 1 :(得分:0)

基本上说,如果在你的赋值语句的左侧,你有重复的值,在这种情况下是 i ,那么值的赋值将从左到右进行。是的,所以你从最左边的值( i )开始,分配它,然后分配下一个( x [i] ),依此类推。

编辑:@iBug说得更好。

答案 2 :(得分:0)

考虑这一点的最简单方法是首先评估右侧(RHS)然后分配到左侧(LHS)。

请注意,当RHS中包含逗号时,它为actually a tuple。当LHS是元组或列表时,它被视为一种特殊语法,其中RHS将被解压缩并分配给LHS上的变量。

因此,当LHS是元组或变量列表时,过程如下:

  1. 构建RHS,从元组的第一个元素开始并继续持续
  2. 解压缩RHS元组并从左到右将元素逐个分配给LHS上的对象。
  3. 换句话说,幕后的Python转为

    (a, b, c) = (x(), y(), z())
    

    进入

    buffer = (x(), y(), z())
    a = buffer[0]
    b = buffer[1]
    c = buffer[2]
    

    https://stackoverflow.com/a/16409962/3830997还有更多相关信息。

    请注意,这可以使用或不使用括号(您不需要括号来创建元组),它可以与LHS上的元组或列表以及RHS上的任何可迭代一起使用。此外,在LHS上命名的变量不必提前存在(这是LHS永远不会组合成正常元组的明显标志)。