我有一个 N 个列表的列表,每个子列表包含 M 个元素。
如何创建一个包含 N 个元素的 M 个列表的列表,每个列表包含初始列表中的第 n 个元素?
假设我有这个
myList = [[1, 2, 3],[4, 5, 6]]
我希望有
[[1, 4],[2, 5],[3, 6]]
性能也很重要。我有数百万个元素的子列表(尽管,一维总是很小:比如 1.000.000 x 8 )
这将给出元组,但扩展它以包含列表是微不足道的:
zip(*myList)
IE
[list(i) for i in zip(*myList)]
>>> lst = [[1, 2, 3], [4, 5, 6]]
>>> zip(*lst)
[(1, 4), (2, 5), (3, 6)]
zip
在 Python 2 中返回一个列表,但在 Python 3 中返回一个迭代器,如果需要,您必须将其转换为列表 ( list(zip(lst))
)
另请参阅:Python 中的矩阵转置、转置/解压缩函数(zip 的倒数)?
zip(*lst)
所做的是将使用运算符的元素解压缩到函数的单独参数中。lst
*
zip
我们知道当我们将两个列表放入时会发生什么:
>>> zip([1, 2, 3], [4, 5, 6])
[(1, 4), (2, 5), (3, 6)]
因此,如果我们有一个包含这两个列表的列表,*
则将解包该列表以形成两个单独的参数——相当于上面的调用。
>>> zip(*[[1, 2, 3], [4, 5, 6]])
[(1, 4), (2, 5), (3, 6)]
采用
myList = [[1, 2, 3],[4, 5, 6]]
zip(*myList )
itertools.izip(*myList)
要从此迭代器创建列表,请执行以下操作:
map(list, itertools.izip(*myList))
既然你提到了效率,我用PyPy尝试了这些,在 100x1000 左右它们开始比zip
(在 CPython 上但它们更差):
myList = [[1, 2, 3],[4, 5, 6]]
newList = [[] for _ in xrange(len(myList[0]))]
for innerList in myList:
for elIdx in xrange(len(innerList)):
newList[elIdx].append(innerList[elIdx])
print newList
我的第一次尝试(更糟),但仍然比zip
PyPy 更好:
newList = [[None for i in xrange(len(myList))] for j in xrange(len(myList[0]))]
for i in xrange(len(myList)):
for j in xrange(len(myList[i])):
newList[j][i] = myList[i][j]
print newList