为什么下一条 python 行不是语法错误?如果真的不是,那么我该如何使用它以及在什么情况下它会有用?
a= range(10)[1:3]=[2,3]
为什么下一条 python 行不是语法错误?如果真的不是,那么我该如何使用它以及在什么情况下它会有用?
a= range(10)[1:3]=[2,3]
Python 支持在同一行进行多个赋值:
>>> a = b = c = 2
>>> a
2
>>> b
2
>>> c
2
由于您将第一个分配给一个列表(python 中的一个可变对象),然后将该列表的一部分(它是可变的)和一个分配给第三个项目的内容,因此 python 可以接受。如果你用不可变的东西替换了你的中间值,你会得到一个错误。
>>> a = 'foo' = 'bar'
File "<input>", line 1
SyntaxError: can't assign to literal
>>> a = {}['foo'] = 'bar'
>>> a
'bar'
有趣的是,这样的行仍然会引发错误,因为您试图将值 3 和 4 分配给字面值 1 和 2。
>>> a = [1, 2] = [3, 4]
File "<input>", line 1
SyntaxError: can't assign to literal
虽然这不会:
>>> a = [1, 2][:] = [3, 4]
>>> a
[3, 4]
在这种情况下,关键是通过使用切片表示法,您将分配给列表内的范围,而不是重新分配给列表中的文字值。
此外,线条
>>> a = [[], []] = [{}, {}]
>>> a
[{}, {}]
和
>>> a = [b, c] = 3, 4
>>> b
3
>>> c
4
是有效的,第一个是因为内部列表和字典都是可变的和可迭代的,第二个是因为您将 3 和 4 分配给变量 b 和 c 而不是文字(感谢 Sven :D)。
编辑回答操作的最后一个问题。
>>> a = 1
>>> b = 2
>>> a,b = b,a = a,b
>>> a
2
>>> b
1
这只是归结为 b,a = a,b 的最终(最右边)分配。观察:
>>> a, b = 'a', 'b'
>>> a, b = b, a = a, b = b, a
>>> a
'b'
>>> b
'a'
>>> a, b = b, a = b, a
>>> a
'a'
>>> b
'b'
这令人困惑,但我对此的解释是在语句完成之前不会重新评估/分配新值 a 和 b,因此重要的分配是最右边的分配。如果最后一条语句是 a、b = a、b 或 b,a = b、a、a 和 b 的值不会改变。如果是a,b = b,a或b,a = a,b,则切换值。
好吧,让我们从 range 函数开始分解一下。range 函数创建一个从 0 到 9 的整数列表。所以你最终得到了这个
[0,1,2,3,4,5,6,7,8,9]
接下来,切片符号将应用于您的整数列表。在冒号之前指定一个数字告诉 python 你想用它作为你的起始索引,因为列表是零索引的,你得到列表中的第二个元素,即值 1。你还给了第二个值提供的数字一个附加索引,因此您将获得不超过该索引的值。但这只会导致第三个元素,它直接跟在起始索引值之后。现在你有了这个:
[1,2]
传统上,在编程语言中,值是从右到左分配的。范围/切片操作似乎在分配之前完成,因为最右边的列表替换了范围操作创建的值。然后将该值再次分配给a。
除非您绝对必须这样做,否则不要像这样重复分配。这是可怕的阅读和理解。最好有可读/更简单的代码。我从来没有用这种方式分配东西。老实说,甚至没有理由处理范围操作,因为它只是被替换了。这只是一个奇怪的东西,最好不要使用。国际海事组织。
这条线确实不是错误,但它从来没有用处。它的作用与
a = [2, 3]
此外,它创建一个包含内容的新列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
,并将该列表的第二项和第三项设置为2
and 3
,最后再次删除该新列表,因为根本没有对它的引用。
这是一个更完整的代码。选择语句的顺序以匹配原始语句的执行顺序:
a = [2, 3]
b = range(10)
b[1:3] = a
del b