如何在Python中将二维数组的列转换为行?

3

我有一个二维的Python数组,长这样:

A = [[186,192,133],[12],[122,193,154],[166,188,199],[133,44,23,56,78,96,100]]

现在我该如何创建一个新数组,使其看起来像这样?
B = [[186,12,122,166,133],[192, 193,188,44],[133,154,199,23],[56],[78],[96],[100]]

我希望将A列转换为B行。
3个回答

1
解决方案
from itertools import izip_longest # in Python 3 zip_longest

list([x for x in y if x is not None] for y in izip_longest(*A))

result:

[[186, 12, 122, 166, 133],
 [192, 193, 188, 44],
 [133, 154, 199, 23],
 [56],
 [78],
 [96],
 [100]]

说明

izip_longest 会给你一个迭代器:

>>> from itertools import izip_longest
>>> izip_longest([1, 2, 3], [4, 5])
<itertools.izip_longest at 0x103331890>

将其转换为列表以查看其作用:

将其转换为列表以查看其作用:

>>> list(izip_longest([1, 2, 3], [4, 5]))
[(1, 4), (2, 5), (3, None)]

它从每个列表中取一个元素并将它们成对放入元组中。此外,它用None(或您提供的其他值)填充缺失值。 *允许为函数提供未指定数量的参数。例如,我们可以将两个列表放在另一个列表中,并使用*,它仍然可以正常工作:
>>> list(izip_longest(*[[1, 2, 3], [4, 5]]))
[(1, 4), (2, 5), (3, None)]

这不仅限于两个参数。以下是一个包含三个参数的示例。

单个参数:

>>> list(izip_longest([1, 2, 3], [4, 5], [6]))
[(1, 4, 6), (2, 5, None), (3, None, None)]

所有参数都在一个列表中,使用*

>>> list(izip_longest(*[[1, 2, 3], [4, 5], [6]]))
[(1, 4, 6), (2, 5, None), (3, None, None)]

你不需要 None 值。使用列表推导式将它们过滤掉:
>>> [x for x in y if x is not None] 

对于你的 A,你得到了这个:
>>> list(izip_longest(*A))
[(186, 12, 122, 166, 133),
 (192, None, 193, 188, 44),
 (133, None, 154, 199, 23),
 (None, None, None, None, 56),
 (None, None, None, None, 78),
 (None, None, None, None, 96),
 (None, None, None, None, 100)]

现在,y遍历此列表中的所有条目,例如(186, 12, 122, 166, 133)。而x遍历y中的每个单独数字,例如186。外部的[]创建一个列表。因此,我们得到了一个列表[186, 12, 122, 166, 133],而不是元组(186, 12, 122, 166, 133)。最后,if x is not None过滤掉None值。

我对Python非常陌生。我尝试查看它的文档,但仍然无法理解。你介意解释一下为什么在izip_longest()中要放*A吗? - Spandyie
1
添加了一些背景信息。 - Mike Müller

1
另一种使用 mapfilter 进行转置的方法:
A = [[186, 192, 133], [12], [122, 193, 154], [166, 188, 199], [133, 44, 23, 56, 78, 96, 100]]


print([list(filter(None,sub)) for sub in map(None,*A)])
[[186, 12, 122, 166, 133], [192, 193, 188, 44], [133, 154, 199, 23], [56], [78], [96], [100]]

如果 0 是一个潜在的值,你需要专门检查 None 的情况:
print([list(filter(lambda x: x is not None, sub)) for sub in map(None,*A)])

或者按照Mikes的答案,使用常规列表表达式进行映射:

 [[x for x in sub if x is not None] for sub in map(None,*A)]

None是函数吗?我想知道这个map(None,*A)是如何工作的?难道它不是像map(function, iterable,...)一样的吗?我以为map()就像R中的lapply()? - Spandyie

0
    def rotate(A):
        B = []
        added = True
        while added:
            added = False
            col = []
            for row in A:
                try:
                    col.append(row.pop(0))
                except IndexError:
                    continue
                added = True
            col and B.append(col)
        return B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接