如何在Python中执行此列表操作?这很棘手

时间:2009-10-11 00:13:38

标签: python list

假设我有这个清单:

[ [5, 44, 73] , [7, 21, 99], [1, 32, 100] ]

将其转换为此列表的最有效方法是什么?

[ 5, 7, 1, 44, 21, 32, 73, 99, 100 ] 

注意,我抓住每个人的第一个。然后是每个的第二个元素。 当然,这个功能需要用X元素完成。

我已经尝试过了,但是我的循环很多,而且我觉得它太长而且很复杂。

感谢。

8 个答案:

答案 0 :(得分:10)

>>> L1 =  [ [5, 44, 73] , [7, 21, 99], [1, 32, 100] ]
>>> L2 = []
>>> map(L2.extend, zip(*L1))
>>> L2
[5, 7, 1, 44, 21, 32, 73, 99, 100]

答案 1 :(得分:8)

import itertools
list(itertools.chain(*zip(*L1)))

如果您需要不同长度的列表:

import itertools
[x for x in itertools.chain(*itertools.izip_longest(*L1)) if x is not None]

答案 2 :(得分:4)

“One-liner”!=“Pythonic”

错误的形式使用列表推导只是为了在一行中实现for循环。如果需要表达式的结果,请保存列表表达式或生成器表达式。我眼中最清晰,最恐怖的是(对于相同长度的子列表):

L1 =  [ [5, 44, 73] , [7, 21, 99], [1, 32, 100] ]
L2 = []
for nextitems in zip(*L1):
    L2.extend(nextitems)

当然你可以将其写成:

[ L2.extend(nextitems) for nextitems in zip(*L1) ]

但只要每个子列表中的项目数量都会生成[None,None,...]的列表,因为extend()返回None。我们在这个清单上做了什么?没什么,所以它立即被丢弃。但是读者必须先了解一下这一点,然后才能意识到这个列表是为了在每个创建的子列表上运行extend()而“构建”的。

Pythonicness是通过使用zip和* L1将L的子列表作为args传递给zip。列表推导通常也被视为Pythonic,但是当它们用于创建事物列表时,而不是for循环的聪明捷径。

答案 3 :(得分:2)

只要所有子列表长度相同:

def flattener(nestedlist):
  if not nestedlist: return []
  return [ x for i in range(len(nestedlist[0]))
             for x in [sublist[i] for sublist in nestedlist]
         ]

例如,

print flattener([ [5, 44, 73] , [7, 21, 99], [1, 32, 100] ])

完全符合你想要的单位清单。

如果并非所有子列表都需要相同的长度,那么当某些子列表更长,更短的时候,您希望发生什么?如果您需要考虑这种不等式,则需要一个精确的规范。

答案 4 :(得分:1)

>>> L1 =  [ [5, 44, 73] , [7, 21, 99], [1, 32, 100] ]
>>> L2 = list(sum(zip(*L1), ()))
>>> L2
[5, 7, 1, 44, 21, 32, 73, 99, 100]

答案 5 :(得分:0)

这是一个O ^ 2解决方案,它假设所有内部数组都具有相同的长度

parent = [ [5, 44, 73] , [7, 21, 99], [1, 32, 100] ]
final = []
for i in range(len(parent[0])):
    for x in range(len(parent)):
        final.append(parent[x][i])
print final # [5, 7, 1, 44, 21, 32, 73, 99, 100]

答案 6 :(得分:0)

对第二个深度的简单列表理解:

>>> L = [ [5, 44, 73] , [7, 21, 99], [1, 32, 100] ]
>>> [x for li in zip(*L) for x in li]
[5, 7, 1, 44, 21, 32, 73, 99, 100]

非常好。如果子列表的长度不均匀,则表达不那么优雅:

>>> L = [ [5, 44, 73] , [7], [1, 32, 100, 101] ]
>>> [li[idx] for idx in xrange(max(map(len, L))) for li in L if idx < len(li)]
[5, 7, 1, 44, 32, 73, 100, 101]

这些解决方案具有复杂度O(n),其中n是元素的总数。

答案 7 :(得分:-2)

只要所有子列表具有相同的长度:

lst = [[5, 44, 73] , [7, 21, 99], [1, 32, 100]]
list(reduce(lambda l, r: l + r, zip(*lst)))

编辑:这将适用于不同长度的子列表:

lst = [[5, 44, 73, 23] , [7, 21, 99], [1, 32, 100]]
list(filter(lambda p: p is not None, reduce(lambda x, y: x + y, map(None, *lst))))