You can create iterators from these lists, iterate over the list of orders 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']
You can 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 order list contains strings, floats or any other objects that cannot be used as list indices, use the 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 also use integers as dictionary keys.
Alternatively, you can remove the items on the left side of each of the source 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']
I expect the first approach will be more efficient ( list.pop(0) slow).