了解Python中的列表解析

hec6srdp  于 2022-12-17  发布在  Python
关注(0)|答案(4)|浏览(222)

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

>>> 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]

我现在更糊涂了!
我应该按什么顺序阅读列表理解?
我确信我没有在任何地方定义过值为9的num变量。

python

输出:

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.

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]
68de4m5k

68de4m5k1#

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

>>> 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]

在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

注意,在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
eagi6jfj

eagi6jfj2#

当执行列表解析时,num的值是9,所以下次迭代vec时,将得到9的列表。
看这个。

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

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

In [3]: num
Out[3]: 9

In [4]: [num for elem in vec]
Out[4]: [9, 9, 9]
disho6za

disho6za3#

让我试着把答案说得更清楚些,顺序显然是从左到右,最右边的值将存储在变量中,即 numelem
初始数据:

vec = [[1,2,3], [4,5,6], [7,8,9]]
num  # Undefined
elem # Undefined

第1步:执行[num for elem in vec for num in elem]行后

# Now the value of undefined variable will be
num = 9  # Will keep the last value of the loop as per Python 2.7
elem = [7, 8, 9]   # The same applies here (as the loop
                   # for 'elem' in 'vec' will get
                   # executed first, followed by
                   # for 'num' in 'elem')

第2步:执行[num for elem in vec]行后

# Output: [9, 9, 9]
# Since num value is 9 and its get repeated 3 times because of
# 'vec' has three elements (three list object in a list, so
# the 'for' loop will run three times)
# Now the variable value would be
num = 9 # No change
elem = [7, 8, 9] # The last tuple of variable vec

步骤3:执行[num for elem in (vec for num in elem)]之后
1.在第一个/右侧循环中,即(vec for num in elem
这里的结果将是一个生成器,由于 elem 的长度为3,它将运行三次。
1.最后的 for 循环将在RESULT 1(长度为3的 for 循环#1的结果)上迭代,并且由于 num 值为9,因此结果将为[9,9,9] # 'num' value重复三次。

js5cn81o

js5cn81o4#

list1 = [num for elem in vec for num in elem]

相当于:

list1 = []
for elem in vec:
    for num in elem:
       list1.append(num)

相关问题