按给定的合并顺序合并两个或多个列表

8
在启动时,我有两个列表和一个指示应该以什么顺序合并这两个列表的列表。 例如,我有第一个列表等于[a, b, c] 和第二个列表等于[d, e],而且“合并”的列表等于[0, 1, 0, 0, 1]
这意味着:要创建合并后的列表,首先需要从第一个列表中取出元素,然后是第二个列表,接着是第一个列表,再接着是第一个列表,然后是第二个列表...最终得到[a, d, b, c, e]。 为了解决这个问题,我只使用了for循环和两个“指针”,但我想知道是否能用更Pythonic的方式完成。我尝试找一些可以帮助我的函数,但没有真正的结果。

1
顺便提一下,这个问题有各种算法可供选择,并且在python - replace the boolean value of a list with the values from two different lists中还有一个计时脚本。 - PM 2Ring
2个回答

17
你可以从这些列表中创建迭代器,循环遍历排序列表,并在其中一个迭代器上调用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) 是一个 的操作)。


2
这个怎么样,
list1 = ['a', 'b', 'c']
list2 = ['d', 'e']
options = [0,1,0,0,1] 

list1_iterator = iter(list1)
list2_iterator = iter(list2)

new_list = [next(list2_iterator) if option else next(list1_iterator) for option in options]

print(new_list)
# Output
['a', 'd', 'b', 'c', 'e']

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