2016-01-30 27 views
5

Dies sind meine zwei Listen;Python - Kreuzung von zwei Listen von Listen

k = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4], [5,9]] 
kDash = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4], [5,6], [1,2]] 

Meine Ausgabe sollte folgende sein;

[[1, 2], [4], [5, 6, 2], [1, 2], [3], [4]] 

Wie kann ich an diesen Ausgang gelangen?

danken Ihnen im Voraus

+0

das Problem, das ich war festgestellt, dass die Unfähigkeit, eine Liste von Listen auf einen Satz Umwandlung, wenn das möglich war diese Kreuzung leicht ergriffen werden könnten, –

+0

Bitte erläutern Sie die Logik, mit der die Ausgabe erhalten wird. – timgeb

+0

Können Sie erklären, warum '[5, 6]' und '[5, 9]' in der Kreuzung sind? – NiziL

Antwort

4

Sie die Listen Liste von Tupeln konvertieren müssen, und dann die Kreuzung verwenden. Beachten Sie, dass unter Lösung Elemente in einer anderen Reihenfolge haben können, und Duplikate werden natürlich nicht da sein, da ich Set verwende.

In [1]: l1 = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4], [5,9]] 

In [2]: l2 = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4], [5,6], [1,2]] 

In [3]: [list(x) for x in set(tuple(x) for x in l1).intersection(set(tuple(x) for x in l2))] 
Out[3]: [[1, 2], [5, 6, 2], [3], [4]] 

Alternativ können Sie die Kreuzung in einer Variablen speichern und die endgültige Liste, wenn Auftrag, Duplikate sind notwendig:

In [4]: intersection = set(tuple(x) for x in l1).intersection(set(tuple(x) for x in l2)) 

In [5]: [x for x in l1 if tuple(x) in intersection] 
Out[5]: [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4]] 

Und die Kreuzung, nur für den Fall, wenn Sie interessiert sind.

In [6]: print intersection 
set([(1, 2), (5, 6, 2), (3,), (4,)]) 

Das wird ziemlich gut für große Listen arbeiten, aber wenn die Listen klein sind, kann die andere Lösung von @timegb erkunden (deren Lösung für längere Listen sehr unoptimal sein)

3

Da Ihre Ausgabeliste hat doppelte Elemente, Sie scheinen nicht wirklich eine klassische Kreuzung zu wollen. Ein grundlegendes Listenverständnis wird alles tun.

>>> k = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4], [5,9]] 
>>> kDash = [[1, 2], [4], [5, 6, 2], [1, 2], [3], [4], [5,6], [1,2]] 
>>> [x for x in k if x in kDash] 
[[1, 2], [4], [5, 6, 2], [1, 2], [3], [4]] 

Für große Listen wollen wir die Zeit, um es __contains__ zu O (1) anstelle von O (n) zu nennen nimmt:

>>> stuff_in_kDash = set(map(tuple, kDash)) 
>>> [x for x in k if tuple(x) in stuff_in_kDash] 
[[1, 2], [4], [5, 6, 2], [1, 2], [3], [4]] 
+0

Und wenn Sie das doppelte Element entfernen müssen, können Sie [diese Antwort] (http://stackoverflow.com/questions/2213923/python-removing-duplicates) betrachten -von-einer-Liste-von-Listen);) – NiziL

+1

Dies ist ein * Los * langsamer als die 'set' Schnittmethoden. Die Skalierung ist etwas wie "O (n²k)", wobei "n" die Anzahl der Unterlisten und "k" die durchschnittliche Länge jeder Unterliste ist. – Veedrac

+0

Ich habe gerade festgestellt, dass die OPs-Ausgabeliste doppelte Elemente hat. Die Liste comp ist also der Weg, wenn sich die Spezifikationen nicht ändern. – timgeb

2

Ein sauberere Weg, um die Kreuzung zu schreiben, ist

{tuple(x) for x in l1} & {tuple(x) for x in l2} 

Eine gute Alternative ist

{tuple(x) for x in l1}.intersection(map(tuple, l2)) 
0

Auch wenn hier was geschrieben wurde, ist viel elegantere Lösungen, hier ist eine andere

def foo(L1,L2): 
    res=[] 
    for lst in L1: 
     if lst in L2: 
      res.append(lst) 
    return res