理解 Python 中的列表推导式

nal*_*zok 1 python list-comprehension python-2.7

在阅读官方教程时,我遇到了这个例子:

>>> vec = [[1,2,3], [4,5,6], [7,8,9]]

>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)

我无法理解这一点,所以我做了一些实验:

>>> [num for elem in vec]
[9, 9, 9]

>>> [num for elem in (vec for num in elem)]
[9, 9, 9]
Run Code Online (Sandbox Code Playgroud)

而我现在更迷茫了!

我应该按什么顺序阅读列表理解?


我确定我没有num在任何地方定义值为 9 的变量。

python
Run Code Online (Sandbox Code Playgroud)

输出:

Python 2.7.10 (default, Oct 23 2015, 19:19:21)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
Run Code Online (Sandbox Code Playgroud)

REPL会话:

>>> num
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'num' is not defined

>>> vec = [[1,2,3], [4,5,6], [7,8,9]]

>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> [num for elem in vec]
[9, 9, 9]

>>> [num for elem in (vec for num in elem)]
[9, 9, 9]
Run Code Online (Sandbox Code Playgroud)

nie*_*mmi 5

列表理解中的循环是从左到右读取的。如果你的列表理解被写成一个普通的循环,它会看起来像这样:

>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> l = []
>>> for elem in vec:
...     for num in elem:
...         l.append(num)
...
>>> l

[1, 2, 3, 4, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)

在 Python 2 中,列表推导式中的变量共享外部作用域,因此num可供稍后使用:

>>> vec = [[1,2,3], [4,5,6], [7,8,9]]

>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> num
9
Run Code Online (Sandbox Code Playgroud)

请注意,在 Python 3 上,行为有所不同:

>>> vec = [[1,2,3], [4,5,6], [7,8,9]]

>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> num
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'num' is not defined
Run Code Online (Sandbox Code Playgroud)