列表理解按列组合子列表的元素

List comprehension to combine elements of sublists by column

我有一个这样的列表:

allrows = [['NEPW46486', 'NEPW46550', 'sersic', 20.04, 21.12],
['NEPW89344', 'NEPW89346', 'sersic', 20.33, 19.66], ...]

我想创建一个新的列表列表,其中每个列表对应一个 "column"。我想要的输出是:

cols = [['NEPW46486', 'NEPW89344', ...], ['NEPW46550', 'NEPW89346', ...], ['sersic', 'sersic', ...], [20.04, 20.33, ...], [21.12, 19.66, ...]]

我想我可以通过列表理解来完成这个,就像这样:

cols = [[row[n] for row in allrows] for n in range(len(row))]

但是我得到一个 NameError 没有定义 row。我还尝试切换我的循环语句的顺序,但这并没有给我想要的输出(相反,它给了我刚开始的结果)。我怎样才能通过列表理解实现我想要的输出?

这就是内置 zip 函数的目的。你只需要在你调用它的时候解压你的列表。类似于:

allrows = [['NEPW46486', 'NEPW46550', 'sersic', 20.04, 21.12],
           ['NEPW89344', 'NEPW89346', 'sersic', 20.33, 19.66]]

for item in zip(*allrows): # unpack with *allrows
    print(item)

网你:

('NEPW46486', 'NEPW89344')
('NEPW46550', 'NEPW89346')
('sersic', 'sersic')
(20.04, 20.33)
(21.12, 19.66)

如果由于某种原因 zip() 不尽如人意,要进行列表理解,通常最简单的方法是制作实际的代码结构,然后对其进行压缩。开始于:

cols = []
for index, item in enumerate(allrows[0]):
    col = []
    for row in allrows:
        col.append(row[index])
    cols.append(col)
print(cols)

我们得到了想要的

[['NEPW46486', 'NEPW89344'], ['NEPW46550', 'NEPW89346'], ['sersic', 'sersic'], [20.04, 20.33], [21.12, 19.66]]

所以我们可以将它压缩成一行,例如:

cols = [[row[index] for row in allrows] for index, item in enumerate(allrows[0])]
print(cols)

再次产生:

[['NEPW46486', 'NEPW89344'], ['NEPW46550', 'NEPW89346'], ['sersic', 'sersic'], [20.04, 20.33], [21.12, 19.66]]

您可以使用 built-in zip() 函数在列表理解中执行此操作,如下所示:

allrows = [['NEPW46486', 'NEPW46550', 'sersic', 20.04, 21.12],
           ['NEPW89344', 'NEPW89346', 'sersic', 20.33, 19.66],]

cols = [list(col) for col in zip(*allrows)]

结果:

[['NEPW46486', 'NEPW89344'], ['NEPW46550', 'NEPW89346'], ['sersic', 'sersic'], [20.04, 20.33], [21.12, 19.66]]

这有时称为“transposing”(意思是将列换成行)二维值矩阵。

如果你只想要一个元组列表,你可以简单地做:

list(zip(*allrows))  # python 3

zip(*allrows)  # python 2