When are parentheses required around a tuple?
当用括号括起来的元组是必需的还是不需要的时候,是否有一个引用精确地定义了?
以下是一个最近让我吃惊的例子:
1 2 3 4 5 6 7
| >>> d = {}
>>> d[0,] = 'potato'
>>> if 0, in d:
File"<stdin>", line 1
if 0, in d:
^
SyntaxError: invalid syntax |
- 我觉得特别有趣的是,在这种情况下,for k, in d: print k确实起作用。
- 例如,python语法将在if语句中显示允许的内容。你必须仔细阅读完整的语法,找出哪里可以接受未附加的元组,这就是为什么我不把它作为答案发布的原因。
- …我不明白你怎么会对for和0,的失败感到惊讶…python标识符必须以(unicode)字母或下划线开头,并且0不是有效的python标识符,因此我希望在那里有一个SyntaxError。
- 这就是为什么大卫说for k,不是for 0,的原因(它成功地将tuple解包到k中,因为dict键是1元素tuple s)
使用逗号标记结合表达式来创建元组被称为expression_list。运算符优先规则不包括表达式列表;这是因为表达式列表本身不是表达式;它们在括在括号中时成为表达式。
因此,在python中的任何地方都允许使用未封闭的expression_list,这是语言语法特别允许的,但在需要expression的地方则不允许。
例如,if语句的语法如下:
1 2 3
| if_stmt ::= "if" expression":" suite
("elif" expression":" suite )*
["else"":" suite] |
由于引用了生产expression,因此不允许未关闭的expression_lists作为if语句的主题。但是,for语句接受expression_list:
1 2
| for_stmt ::= "for" target_list"in" expression_list":" suite
["else"":" suite] |
号
因此,允许以下内容:
1 2
| for x in 1, 2, 3:
print(x) |
- +1这当然解释了为什么for k, in d起作用(因为for k, v in d起作用)。
- 问题:你应该把它写在for x in 1, 2, 3:还是for x in (1, 2, 3):上?我一直是用第二种方式写的,但那是因为我直到现在才知道第一种方式是有效的。现在我想知道,()是否是不必要的噪声,或者它们是否有助于阅读代码。PEP8是否对此提供任何指导?
- @《兵法》在《政治公众人物8》中没有具体的指导。它可能有助于与if语句进行比较,其中括号仅适用于跨多行的条件。那么:for x in (1, 2, 3):。
在任何允许使用expression_list术语的地方,都不需要使用括号。
if语句需要expression,不支持expression_list。
允许使用expression_list的语法示例:
- return声明
- yield表达式
- 分配(包括增援任务)
- for号声明。
grepping表达式、expression_list的简单和复合语句文档将告诉您在Python语法中使用expression_list的所有位置。
- 哦,是吗?埃多克斯1〔7〕怎么样?它不会导致您可能期望的表达式列表…
- @smci这和我的答案有什么关系?你期待什么结果?
- 因为1,2,3 + 4,5导致表达式1,2,7,5的出现,这不是普通读者所期望的,而是来自于对序列追加的+的重载。
- @很抱歉,但是我想我是说1, 2, 7, 5。逗号之间的每一部分都是一个表达式;整体是一个expression_list。不存在求和表达式列表的语法规则;相反,+是包含表达式之一(3 + 4的一部分)。要添加两个元组,请通过添加括号来创建两个单独的表达式。
- 是的,我知道。但是,非python用户或缺少尾部逗号的用户希望使用连接的tuple 1,2,3, + 4,5,。尾随逗号有什么不同。
- @smci:通过加逗号,你把表达式改为+4,也就是4。您仍然没有连接两个元组,而是用产生4的+4定义一个元组。
- Martijn我知道,当我发布它时,我故意发布它,以说明可能存在(在本例中,是视觉)模糊的情况,在这种情况下,强烈建议使用括号。我不是要你解释它,只是要指出歧义可能存在。
为了避免歧义,还需要括号。
以下是两个不同的表达式…只是因为某个东西是"表达式列表",不会导致您可能期望的表达式列表:)
1 2
| (1, 2, 3) + (4, 5) # results in (1, 2, 3, 4, 5) because + does sequence.extend on the tuples
1, 2, 3 + 4, 5 # this results in (1, 2, 7, 5) because + adds the elements, since there were no parentheses to protect the separate tuples |
。