Python - () 和 [] 的机制

mon*_*mon 4 python

它看起来e for e in [1, 2, 3, 4, 5]是一个生成器表达式,(e for e in [1, 2, 3, 4, 5])并被评估为一个生成器对象。因此,我认为(...)是 Python 中的评估。

我想list(e for e in [1, 2, 3, 4, 5])是告诉 Python 运行时评估可迭代表达式,生成它的对象,并调用list函数来调用,yield直到它用完元素。

print(list(e for e in [1, 2, 3, 4, 5]))
---
[1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)

[...]下面的代码实际上是什么,它的机制是什么?[ e for e in [1, 2, 3, 4, 5] ]生成一个列表对象,因此我认为它是e for e in [1, 2, 3, 4, 5]对创建生成器对象的评估和调用对生成器对象的调用的组合。它是函数调用的别名list(...)吗?

print([ e for e in [1, 2, 3, 4, 5] ])
---
[1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)

对于使用切片对象的列表访问,我想[1:3]是告诉 Python 评估 1:3表达式以生成切片对象。

print([1,2,3][1:3])
print([1,2,3][slice(1,3,1)])
---
[2, 3]
[2, 3]
Run Code Online (Sandbox Code Playgroud)

[(1:3)]失败,因为它试图评估已经评估1:3

print([1,2,3][(1:3)])
---
  File "<ipython-input-167-c20e211025dc>", line 1
    print([1,2,3][(1:3)])
                    ^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)

Gre*_*Guy 9

[1, 2, 3, 4, 5] 是一个列表文字。

value for item in iterable是一个生成器理解。list(value for item in iterable)list()使用生成器调用构造函数,这当然只是生成一个列表。为了减少歧义,不能赤裸裸地使用生成器理解。但它既可以在一组括号内使用,也可以在另一个表达式内使用,例如函数调用中的参数。类似的限制适用:=于 Python 3.8 中添加的(walrus) 运算符。

[value for item in iterable]是一个列表理解。请注意,Python 将其视为一个完全独立的语法结构

实现可能大致相同,但据我所知,Python 编译器在处理代码时分别检测生成器推导式和列表推导式,并且列表推导式并未定义为生成器理解或列表文字。


我很确定类似的事情适用于切片语法 - 它被定义为它自己的语法,特别是在列表索引的上下文中,而不是在其他上下文中。lst[1:3]编译成lst.__getitem__(slice(1, 3))是编译过程的一部分,对于语法来说不是一般的事情1:3(因为那是模棱两可的)。

换句话说,如果我没记错的话,lst[x:y:z]lst[x]Python 编译器而言,它与 是不同的句法构造 。


*本文中的信息基于我对 CPython 源代码中各种方法的理解和之前的交互。我在语法、编译器和可能无效的编译代码之间得出了一些结论。