为什么下一个python行不是语法错误?如果它真的不是那么我怎么能使用它,在哪种情况下它会有用?
a= range(10)[1:3]=[2,3]
答案 0 :(得分:6)
Python在同一行支持多个赋值:
>>> a = b = c = 2
>>> a
2
>>> b
2
>>> c
2
由于您要将第一个分配给列表(python中的可变对象),然后将该列表的两个部分(可变)和a分配给第三个项目的内容,因此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
是有效的,第一个是因为内部列表和dicts都是可变的和可迭代的,第二个是因为你将3和4分配给变量b和c而不是文字(感谢Sven:D)。 / p>
修改要回答操作的最终问题。
>>> 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,则切换值。
答案 1 :(得分:2)
这一行确实不是错误,但它永远不会有用。它和
一样a = [2, 3]
此外,它会创建一个包含内容[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
的新列表,并将此列表的第二项和第三项设置为2
和3
,最后再次删除此新列表完全没有参考。
这是一个更完整的代码。选择语句的顺序以匹配原始语句的执行顺序:
a = [2, 3]
b = range(10)
b[1:3] = a
del b
答案 2 :(得分:2)
让我们从范围函数开始稍微分解一下。范围函数创建一个0到9的整数列表。所以你最终得到了这个
[0,1,2,3,4,5,6,7,8,9]
接下来,切片表示法将应用于整数列表。在冒号之前指定一个数字告诉python你要将它用作起始索引,并且因为列表是零索引的,你得到列表中的第二个元素是值1.你还给了第二个值来提供的数字另外一个索引,因此您将获得该索引的值。但这只会产生第三个元素,它直接跟在起始索引值之后。现在你有了这个:
[1,2]
传统上,在编程语言中,值从右到左分配。看起来范围/切片操作在分配之前完成,因为最右边的列表替换了范围操作创建的值。然后将该值再次分配给。
除非你绝对必须,否则不要像这样双重分配。阅读和理解这很糟糕。拥有可读/更简单的代码会更好。我从来没有用这种方式分配东西。老实说,没有理由甚至处理范围操作,因为它无论如何都被替换了。这只是一个奇怪的最好未使用。 IMO。