繁体   English   中英

合并不同长度的python列表

[英]Merge python lists of different lengths

我试图合并两个python列表,其中给定索引的值将在新列表中形成一个列表(元素)。 例如:

merge_lists([1,2,3,4], [1,5]) = [[1,1], [2,5], [3], [4]]

我可以迭代这个函数来组合更多的列表。 实现这一目标的最有效方法是什么?

编辑(第2部分)

在测试了我之前选择的答案后,我意识到我有其他标准和更普遍的问题。 我还想结合包含列表值的列表。 例如:

merge_lists([[1,2],[1]] , [3,4]) = [[1,2,3], [1,4]]

目前提供的答案会在这种情况下生成更高维度的列表。

一种选择是使用itertools.zip_longest (在python 3中):

from itertools import zip_longest    

[[x for x in t if x is not None] for t in zip_longest([1,2,3,4], [1,5])]
# [[1, 1], [2, 5], [3], [4]]

如果您喜欢套装:

[{x for x in t if x is not None} for t in zip_longest([1,2,3,4], [1,5])]
# [{1}, {2, 5}, {3}, {4}]

在python 2中,使用itertools.izip_longest

from itertools import izip_longest    

[[x for x in t if x is not None] for t in izip_longest([1,2,3,4], [1,5])]
#[[1, 1], [2, 5], [3], [4]]

更新以处理稍微复杂的情况:

def flatten(lst):

    result = []
    for s in lst:
        if isinstance(s, list):
            result.extend(s)
        else:
            result.append(s)

    return result

这很好地处理了上述两种情况:

[flatten(x for x in t if x is not None) for t in izip_longest([1,2,3,4], [1,5])]
# [[1, 1], [2, 5], [3], [4]]

[flatten(x for x in t if x is not None) for t in izip_longest([[1,2],[1]] , [3,4])]
# [[1, 2, 3], [1, 4]]

注意即使这适用于上述两种情况,但它仍然可以在更深层次的嵌套结构下破解,因为案例可能会很快变得复杂。 有关更通用的解决方案,请参阅此处

你可以使用itertools.izip_longestfilter()

>>> lst1, lst2 = [1, 2, 3, 4], [1, 5]
>>> from itertools import izip_longest
>>> [list(filter(None, x)) for x in izip_longest(lst1, lst2)]
[[1, 1], [2, 5], [3], [4]]

工作原理: izip_longest()聚合两个列表中的元素,使用None s填充缺失值,然后使用filter()过滤掉。

使用zip()获得所需输出的另一种方法:

 def merge(a, b):
     m = min(len(a), len(b))
     sub = []
     for k,v in zip(a,b):
         sub.append([k, v])
     return sub + list([k] for k in a[m:]) if len(a) > len(b) else sub + list([k] for k in b[m:])

a = [1, 2, 3, 4]
b = [1, 5]
print(merge(a, b))
>>> [[1, 1], [2, 5], [3], [4]]

使用来自itertools的zip_longest和链的另一种方法:

import itertools
[i for i in list(itertools.chain(*itertools.zip_longest(list1, list2, list3))) if i is not None]

或2行(更易读):

merged_list = list(itertools.chain(*itertools.zip_longest(a, b, c)))
merged_list = [i for i in merged_list if i is not None]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM