为什么这条python线不是错误?

时间:2012-04-06 23:30:32

标签: python syntax syntax-error

为什么下一个python行不是语法错误?如果它真的不是那么我怎么能使用它,在哪种情况下它会有用?

 a= range(10)[1:3]=[2,3]

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]的新列表,并将此列表的第二项和第三项设置为23,最后再次删除此新列表完全没有参考。

这是一个更完整的代码。选择语句的顺序以匹配原始语句的执行顺序:

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。