2015-05-18 16 views
5

Przede wszystkim chciałem powiedzieć, że mój tytuł prawdopodobnie nie opisuje poprawnie mojego pytania. Nie wiem, jak proces, który próbuję osiągnąć, jest nazywany, co sprawiło, że szukanie rozwiązania na stackoverflow lub google było bardzo trudne. Wskazówka dotycząca tego może mi już bardzo pomóc!Python: Połączenie w listach list (?)

To, co obecnie mam, to w zasadzie dwie listy z listami jako elementami. Przykład:

List1 = [ [a,b], [c,d,e], [f] ] 
List2 = [ [g,h,i], [j], [k,l] ] 

Te listy są zasadniczo wierzchołki grafu próbuję utworzyć później w moim projekcie, gdzie krawędzie mają być od List1 do lista2 wierszami.

Jeśli spojrzymy na pierwszym wierszu każdej z list, ja zatem:

[a,b] -> [g,h,i] 

Jednakże chcę mieć assingments/krawędzie unikalnych elementów, więc muszę:

[a] -> [g] 
[a] -> [h] 
[a] -> [i] 
[b] -> [g] 
[b] -> [h] 
[b] -> [i] 

wynik Chcę mieć to kolejna lista, z tych unikalnych assigments jako elementów, tj

List3 = [ [a,g], [a,h], [a,i], [b,g], ...] 

Czy istnieje jakiś elegancki sposób na przejście z List1 i List2 na Listę 3?

Sposób, w jaki chciałem tego dokonać, polega na przechodzeniu wiersz po wierszu, określaniu ilości elementów każdego wiersza, a następnie zapisywaniu klauzul i pętli w celu utworzenia nowej listy z wszystkimi możliwymi kombinacjami. To jednak wydaje się być bardzo nieefektywnym sposobem.

+0

Wygląda jak chcesz, 'itertools. produkt "każdej pary" utworzony przez 'zip'ping (lub' itertools.izip' w 2.x) obie listy razem. – jonrsharpe

+0

@jonrsharpe pobili mnie, ale zgadzam się, to jest praca dla itertools (https://docs.python.org/2/library/itertools.html) – firelynx

+0

Dziękuję za komentarze, myślę, że to jest dokładnie to Szukałem! Poniżej wypróbowałem rozwiązanie przedstawione przez Cyber. – user4911943

Odpowiedz

13

Możesz zip twoich dwóch list, a następnie użyj itertools.product, aby utworzyć każdą ze swoich kombinacji. Możesz użyć itertools.chain.from_iterable, aby spłaszczyć wynikową listę.

>>> import itertools 
>>> List1 = [ ['a','b'], ['c','d','e'], ['f'] ] 
>>> List2 = [ ['g','h','i'], ['j'], ['k','l'] ] 
>>> list(itertools.chain.from_iterable(itertools.product(a,b) for a,b in zip(List1, List2))) 
[('a', 'g'), ('a', 'h'), ('a', 'i'), ('b', 'g'), ('b', 'h'), ('b', 'i'), ('c', 'j'), ('d', 'j'), ('e', 'j'), ('f', 'k'), ('f', 'l')] 
+0

od kiedy używasz itertools, możesz równie dobrze łańcuch –

+1

o tak :) dobry złapać – CoryKramer

+1

'chain.from_iterable' może być użyty do spłaszczenia listy. Oczywiście możesz potrzebować dodatkowego wywołania 'list()' jeśli generator nie jest wystarczający. – Matthias

0
import itertools 
k = [] 
for a,b in zip(List1,List2): 
    for j in itertools.product(a,b): 
     k.append(j) 
print k 
+0

Niektóre podobne do powyższego rozwiązania bez użycia itertools.chain() – rajeshv90

2

Jeśli nie chcesz używać itertools, można również używać w połączeniu z list comprehensionszip to zrobić dość elegancko:

lst1 = [['a','b'], ['c','d','e'], ['f']] 
lst2 = [['g','h','i'], ['j'], ['k','l']] 
edges = [[x, y] for il1, il2 in zip(lst1, lst2) for x in il1 for y in il2]