为什么列表理解中的元组需要括号?[重复]


问题内容

这个问题已经在这里有了答案

为什么使用列表推导创建元组列表需要括号? (2个答案)

8个月前关闭。

众所周知,元组不是用括号定义的,而是逗号。引用文档

一个元组包含多个用逗号分隔的值

因此:

myVar1 = 'a', 'b', 'c'
type(myVar1)
# Result:
<type 'tuple'>

另一个引人注目的示例是:

myVar2 = ('a')
type(myVar2)
# Result:
<type 'str'>

myVar3 = ('a',)
type(myVar3)
# Result:
<type 'tuple'>

甚至单元素元组也需要逗号,并且始终使用括号只是为了避免混淆。 我的问题是: 为什么我们不能在列表推导中省略数组的括号?例如:

myList1 = ['a', 'b']
myList2 = ['c', 'd']

print([(v1,v2) for v1 in myList1 for v2 in myList2])
# Works, result:
[('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd')]

print([v1,v2 for v1 in myList1 for v2 in myList2])
# Does not work, result:
SyntaxError: invalid syntax

第二个列表理解只是以下循环的语法糖,它起作用吗?

myTuples = []
for v1 in myList1:
    for v2 in myList2:
        myTuple = v1,v2
        myTuples.append(myTuple)
print myTuples
# Result:
[('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd')]

问题答案:

Python的语法是LL(1),这意味着它在解析时仅向前看一个符号。

[(v1, v2) for v1 in myList1 for v2 in myList2]

在这里,解析器看到这样的内容。

[ # An opening bracket; must be some kind of list
[( # Okay, so a list containing some value in parentheses
[(v1
[(v1,
[(v1, v2
[(v1, v2)
[(v1, v2) for # Alright, list comprehension

但是,如果没有括号,则必须更早地做出决定。

[v1, v2 for v1 in myList1 for v2 in myList2]

[ # List-ish thing
[v1 # List containing a value; alright
[v1, # List containing at least two values
[v1, v2 # Here's the second value
[v1, v2 for # Wait, what?

众所周知,回溯的解析器通常很慢,因此LL(1)解析器不会回溯。因此,模棱两可的语法是被禁止的。