为什么在表达式字段中不允许生成器中未加括号的元组?
Why are unparanthesized tuples in generators not allowed in the expression field?
# why is the following invalid
x = (k, v for k, v in some_dict.items())
# but if we wrap the expression part in parentheses it works
x = ((k, v) for k, v in some_dict.items())
我查看了文档,似乎没有找到任何相关信息?什么可能会使解析器混淆语法是不允许的?尽管有更复杂的工作:
# k, v somehow confuses the parser but this doesnt???
x = ('%s:%s:%s' % (k, v, k) for k, v in some_dict.items())
为什么我们不需要用括号包裹 %s:%s:%s % (k, v, k)
?
看看x = (k, v for k, v in some_dict.items())
:
x = (k, v for k, v in some_dict.items())
x = ((k, v) for k, v in some_dict.items())
x = (k, (v for k, v in some_dict.items()))
需要括号来消除歧义。
x = ('%s:%s:%s' % (k, v, k) for k, v in some_dict.items())
也需要括号:
x = ('%s:%s:%s' % k, v, k for k, v in some_dict.items())
x = ('%s:%s:%s' % k, (v, k) for k, v in some_dict.items())
x = ('%s:%s:%s' % (k, v, k) for k, v in some_dict.items())
碰巧你已经有足够的括号来解决那里的歧义,以允许它以预期的方式运行。
Python 的解析器解析这个
x = (k, v for k, v in some_dict.items())
作为包含 k
和生成器表达式的元组:
v for k, v in some_dict.items()
但这不是一个有效的生成器表达式:它必须是,正如 PEP 289 所说:
directly inside a set of parentheses and cannot have a comma on either side
Python在这里看到的生成器不是直接在一组括号内,确实有一个逗号一方面,所以这是非法的。
之所以这样认为是因为解析器(故意)非常简单。特别是,它是一个 LL(1) 解析器,意思是:
- 从左到右扫描标记;
- 考虑当前标记和下一个标记(先行标记);和
- 尽快决定表达式的含义
因此,它到达当前标记 k
,并看到下一个是逗号。这是一个元组,它坚持那个决定。它只会在稍后看到 for
(当当前标记为 v
时),因此它成为生成器表达式 inside 元组。解析器不会回溯以查看是否存在潜在的合法表达式解析(存在 - 你想要的元组位于生成器表达式内,但可能并不总是存在),它只是立即抛出错误。
# why is the following invalid
x = (k, v for k, v in some_dict.items())
# but if we wrap the expression part in parentheses it works
x = ((k, v) for k, v in some_dict.items())
我查看了文档,似乎没有找到任何相关信息?什么可能会使解析器混淆语法是不允许的?尽管有更复杂的工作:
# k, v somehow confuses the parser but this doesnt???
x = ('%s:%s:%s' % (k, v, k) for k, v in some_dict.items())
为什么我们不需要用括号包裹 %s:%s:%s % (k, v, k)
?
看看x = (k, v for k, v in some_dict.items())
:
x = (k, v for k, v in some_dict.items())
x = ((k, v) for k, v in some_dict.items())
x = (k, (v for k, v in some_dict.items()))
需要括号来消除歧义。
x = ('%s:%s:%s' % (k, v, k) for k, v in some_dict.items())
也需要括号:
x = ('%s:%s:%s' % k, v, k for k, v in some_dict.items())
x = ('%s:%s:%s' % k, (v, k) for k, v in some_dict.items())
x = ('%s:%s:%s' % (k, v, k) for k, v in some_dict.items())
碰巧你已经有足够的括号来解决那里的歧义,以允许它以预期的方式运行。
Python 的解析器解析这个
x = (k, v for k, v in some_dict.items())
作为包含 k
和生成器表达式的元组:
v for k, v in some_dict.items()
但这不是一个有效的生成器表达式:它必须是,正如 PEP 289 所说:
directly inside a set of parentheses and cannot have a comma on either side
Python在这里看到的生成器不是直接在一组括号内,确实有一个逗号一方面,所以这是非法的。
之所以这样认为是因为解析器(故意)非常简单。特别是,它是一个 LL(1) 解析器,意思是:
- 从左到右扫描标记;
- 考虑当前标记和下一个标记(先行标记);和
- 尽快决定表达式的含义
因此,它到达当前标记 k
,并看到下一个是逗号。这是一个元组,它坚持那个决定。它只会在稍后看到 for
(当当前标记为 v
时),因此它成为生成器表达式 inside 元组。解析器不会回溯以查看是否存在潜在的合法表达式解析(存在 - 你想要的元组位于生成器表达式内,但可能并不总是存在),它只是立即抛出错误。