Można utworzyć iteratory z tych list, pętla listę zamawiania i nazywają next
na jednym z iteratorów:
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']
Jest to możliwe do uogólnienia tego roztworu do dowolnej liczby list, jak pokazano poniżej
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]
Jeśli lista zawiera zamawiania strun, pływaków, lub wszelkie inne przedmioty, które mogą „T być używany jako lista indeksów, należy użyć słownika:
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]
Oczywiście, można użyć liczb całkowitych jako klucze słownika, jak również.
Można również usuwać elementy z lewej strony każdej z oryginalnych list jeden po drugim i dodawać je do wynikowej listy. Krótki przykład:
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']
spodziewałbym pierwsze podejście jest bardziej wydajne (list.pop(0)
jest powolny).
FWIW, istnieje wiele różnych algorytmów dla tego problemu, jak również skrypt rozrządu w [python - wymienić logiczną wartość listy z wartościami z dwóch różnych listach ] (http://stackoverflow.com/q/42028606/4014959). –