开始时,我有 2 个列表和 1 个列表,其中说明我应该按什么顺序合并这两个列表。例如,我有第一个列表等于[a, b, c],第二个列表等于[d, e],并且“合并”列表等于[0, 1, 0, 0, 1]。
[a, b, c]
[d, e]
[0, 1, 0, 0, 1]
这意味着:为了制作合并列表,首先我需要从第一个列表中取出元素,然后是第二个,然后是第一个,然后是第一个,然后是第二个…最后得到[a, d, b, c, e]。为了解决这个问题,我只使用了 for 循环和两个“指针”,但我想知道我是否可以更像 Python 地完成这项任务…我试图找到一些可以帮助我的函数,但没有真正的结果。
[a, d, b, c, e]
您可以从这些列表创建迭代器,循环遍历排序列表,并调用next其中一个迭代器:
next
i1 = iter(['a', 'b', 'c']) i2 = iter(['d', 'e']) # Select the iterator to advance: `i2` if `x` == 1, `i1` otherwise print([next(i2 if x else i1) for x in [0, 1, 0, 0, 1]]) # ['a', 'd', 'b', 'c', 'e']
可以将此解决方案推广到任意数量的列表,如下所示
def ordered_merge(lists, selector): its = [iter(l) for l in lists] for i in selector: yield next(its[i]) In [4]: list(ordered_merge([[3, 4], [1, 5], [2, 6]], [1, 2, 0, 0, 1, 2])) Out[4]: [1, 2, 3, 4, 5, 6]
如果排序列表包含字符串、浮点数或任何其他不能用作列表索引的对象,请使用字典:
def ordered_merge(mapping, selector): its = {k: iter(v) for k, v in mapping.items()} for i in selector: yield next(its[i]) In [6]: mapping = {'A': [3, 4], 'B': [1, 5], 'C': [2, 6]} In [7]: list(ordered_merge(mapping, ['B', 'C', 'A', 'A', 'B', 'C'])) Out[7]: [1, 2, 3, 4, 5, 6]
当然,您也可以使用整数作为字典键。
或者,你可以逐个从每个原始列表的左侧删除元素,然后将它们添加到结果列表中。快速示例:
In [8]: A = ['a', 'b', 'c'] ...: B = ['d', 'e'] ...: selector = [0, 1, 0, 0, 1] ...: In [9]: [B.pop(0) if x else A.pop(0) for x in selector] Out[9]: ['a', 'd', 'b', 'c', 'e']
我希望第一种方法更有效(list.pop(0)但很慢)。
list.pop(0)