我相信我在试图弄清楚如何正确地提出问题时回答了我自己的问题,但由于我发现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分配给整数,并且打算将该前一个整数用作索引而不是新值,则执行的不透明性会更加复杂。
顺便说一句,这是我第一次提出问题,所以我没有必要的声誉来发表我自己的答案。请随时提供任何建设性的建议,告诉我如何改进我可能会提出的任何未来问题,或者我如何更好地为这个社区做出贡献。感谢。
答案 0 :(得分:0)
也许这是一个英文问题?
在分配给变量的集合中重叠 从左到右重叠
因此,LHS是#34;分配给变量的集合"。换句话说,"分配给变量"是将赋值的变量,即LHS。
"在LHS"中重叠表示一个变量引用的对象取决于另一个。在您的示例中,c[i]
引用的对象取决于i
,因此
i, c[i] = 4, 99
从左到右运行。
然而,在下一次测试中:
c, d = 9, print(c)
由于LHS变量c
和d
不重叠(相互依赖),因此c
和d
的分配是平行的。
答案 1 :(得分:0)
基本上说,如果在你的赋值语句的左侧,你有重复的值,在这种情况下是 i ,那么值的赋值将从左到右进行。是的,所以你从最左边的值( i )开始,分配它,然后分配下一个( x [i] ),依此类推。
编辑:@iBug说得更好。
答案 2 :(得分:0)
考虑这一点的最简单方法是首先评估右侧(RHS)然后分配到左侧(LHS)。
请注意,当RHS中包含逗号时,它为actually a tuple。当LHS是元组或列表时,它被视为一种特殊语法,其中RHS将被解压缩并分配给LHS上的变量。
因此,当LHS是元组或变量列表时,过程如下:
换句话说,幕后的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永远不会组合成正常元组的明显标志)。