2016-05-18 14 views
7

Na początku mam 2 listy i 1 listę, która mówi w jakiej kolejności powinienem scalić te dwie listy. Na przykład mam pierwszą listę równą [a, b, c] i drugą listę równą [d, e] i listę "scalania" równą [0, 1, 0, 0, 1].Scalenie dwóch lub więcej list z podaną kolejnością łączenia

To znaczy: aby najpierw utworzyć scaloną listę, muszę wziąć element z pierwszej listy, potem drugi, potem pierwszy, potem pierwszy, potem drugi ... I kończę na [a, d, b, c, e]. Aby rozwiązać ten problem, użyłem tylko pętli i dwóch "wskaźników", ale zastanawiałem się, czy mogę wykonać to zadanie bardziej pytonowo ... Próbowałem znaleźć funkcje, które mogłyby mi pomóc, ale nie przyniosłyby rzeczywistych rezultatów.

+0

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). –

Odpowiedz

14

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).

2

Jak o tym,

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'] 
Powiązane problemy