列表推导替代二维矩阵中的for循环

29 投票
1 回答
93302 浏览
提问于 2025-04-18 17:32

我尝试用列表推导式来替代for循环。

原始文件是

2 3 4 5 6 3
1 2 2 4 5 5
1 2 2 2 2 4

for循环

line_number = 0
for line in file:
    line_data = line.split()
    Cordi[line_number, :5] = line_data 
    line_number += 1

输出是

[[2 3 4 5 6 3]
 [1 2 2 4 5 5]
 [1 2 2 2 2 4]]

如果用列表推导式来代替,我想到的方式是(我必须把数据类型改成整数,这样才能在程序后面的部分进行绘图)

Cordi1= [int(x) for x in line.split() for line in data]

但是输出是

[1, 1, 1]

不过line.split() for line in data实际上是一个列表,如果我尝试

Cordi1 = [int(x) for x in name of the list]

它可以工作,为什么会这样呢?

1 个回答

66

你的循环顺序搞错了;它们应该按照嵌套的顺序,从左到右排列:

[int(x) for line in data for x in line.split()]

这个代码先遍历 data,然后对于每一行 line,再遍历 line.split() 来生成 x。最后,你会从这些数据中生成一个扁平的整数列表。

不过,因为你想要创建一个列表的列表,所以需要把一个列表推导式放在另一个里面:

Cordi1 = [[int(i) for i in line.split()] for line in data]

示例:

>>> data = '''\
... 2 3 4 5 6 3
... 1 2 2 4 5 5
... 1 2 2 2 2 4
... '''.splitlines()
>>> [int(x) for line in data for x in line.split()]
[2, 3, 4, 5, 6, 3, 1, 2, 2, 4, 5, 5, 1, 2, 2, 2, 2, 4]
>>> [[int(i) for i in line.split()] for line in data]
[[2, 3, 4, 5, 6, 3], [1, 2, 2, 4, 5, 5], [1, 2, 2, 2, 2, 4]]

如果你想从这个数据创建一个多维的 numpy 数组,你可以直接把上面的结果转换成数组,或者先从数据创建一个数组,然后再调整形状:

>>> import numpy as np
>>> np.array([[int(i) for i in line.split()] for line in data])
array([[2, 3, 4, 5, 6, 3],
       [1, 2, 2, 4, 5, 5],
       [1, 2, 2, 2, 2, 4]])
>>> np.array([int(i) for line in data for i in line.split()]).reshape((3, 6))
array([[2, 3, 4, 5, 6, 3],
       [1, 2, 2, 4, 5, 5],
       [1, 2, 2, 2, 2, 4]])

撰写回答