问题描述
一开始我有 2 个列表和 1 个列表,说明我应该以什么顺序合并这两个列表.例如,我的第一个列表等于 [a, b, c]
,第二个列表等于 [d, e]
,'merging' 列表等于 [0, 1, 0, 0, 1]
.
On start I have 2 lists and 1 list that says in what order I should merge those two lists.For example I have first list equal to [a, b, c]
and second list equal to [d, e]
and 'merging' list equal to [0, 1, 0, 0, 1]
.
这意味着:要首先制作合并列表,我需要从第一个列表中获取元素,然后是第二个,然后是第一个,然后是第一个,然后是第二个......最后我得到 [a, d, b, c, e]
.为了解决这个问题,我只使用了 for 循环和两个指针",但我想知道我是否可以更 Python 地完成这个任务......我试图找到一些可以帮助我的函数,但没有真正的结果.
That means: to make merged list first I need to take element from first list, then second, then first, then first, then second... And I end up with [a, d, b, c, e]
.To solve this I just used for loop and two "pointers", but I was wondering if I can do this task more pythonic... I tried to find some functions that could help me, but no real result.
推荐答案
您可以从这些列表创建迭代器,遍历排序列表,并调用 next
在其中一个迭代器上:
You could create iterators from those lists, loop through the ordering list, and call next
on one of the iterators:
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']
可以将此解决方案推广到任意数量的列表,如下所示
It's possible to generalize this solution to any number of lists as shown below
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]
如果排序列表包含字符串、浮点数或任何其他不能用作列表索引的对象,请使用字典:
If the ordering list contains strings, floats, or any other objects that can't be used as list indexes, use a dictionary:
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]
当然,您也可以使用整数作为字典键.
Of course, you can use integers as dictionary keys as well.
或者,您可以从每个原始列表的左侧逐个删除元素,然后将它们添加到结果列表中.快速示例:
Alternatively, you could remove elements from the left side of each of the original lists one by one and add them to the resulting list. Quick example:
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)
慢).
I would expect the first approach to be more efficient (list.pop(0)
is slow).
这篇关于以给定的合并顺序合并两个或多个列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!