477 Stimmen

Schnittpunkt von zwei verschachtelten Listen finden?

Ich weiß, wie man eine Schnittmenge von zwei flachen Listen erhält:

b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
b3 = [val for val in b1 if val in b2]

ou

def intersect(a, b):
    return list(set(a) & set(b))

print intersect(b1, b2)

Aber wenn ich eine Schnittmenge für verschachtelte Listen finden muss, fangen meine Probleme an:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

Am Ende würde ich gerne erhalten:

c3 = [[13,32],[7,13,28],[1,6]]

Könnt ihr mir dabei behilflich sein?

Verwandte Seiten

897voto

S.Lott Punkte 371691

Sie brauchen keine Kreuzung zu definieren. Sie ist bereits ein erstklassiger Bestandteil von set.

>>> b1 = [1,2,3,4,5,9,11,15]
>>> b2 = [4,5,6,7,8]
>>> set(b1).intersection(b2)
set([4, 5])

179voto

Brian R. Bondy Punkte 325712

Wenn Sie wollen:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
c3 = [[13, 32], [7, 13, 28], [1,6]]

Dann ist hier Ihre Lösung für Python 2:

c3 = [filter(lambda x: x in c1, sublist) for sublist in c2]

In Python 3 filter gibt eine Iterable zurück anstelle von list Sie müssen also Folgendes einpacken filter Anrufe mit list() :

c3 = [list(filter(lambda x: x in c1, sublist)) for sublist in c2]

Erläuterung:

Im Filterteil wird für jedes Element der Unterliste geprüft, ob es in der Ausgangsliste c1 enthalten ist. Das Listenverständnis wird für jede Teilliste in c2 ausgeführt.

61voto

Zack Burt Punkte 7768

Für Leute, die nur die Schnittmenge zweier Listen suchen, hat der Fragesteller zwei Methoden bereitgestellt:

b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
b3 = [val for val in b1 if val in b2]

y

def intersect(a, b):
     return list(set(a) & set(b))

print intersect(b1, b2)

Es gibt jedoch eine hybride Methode, die effizienter ist, weil Sie nur eine Umwandlung zwischen Liste und Menge vornehmen müssen, statt drei:

b1 = [1,2,3,4,5]
b2 = [3,4,5,6]
s2 = set(b2)
b3 = [val for val in b1 if val in s2]

Dies läuft in O(n), während seine ursprüngliche Methode mit Listenverständnis in O(n^2) läuft

30voto

pufferfish Punkte 15359

Der funktionale Ansatz:

input_list = [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7]]

result = reduce(set.intersection, map(set, input_list))

und kann auf den allgemeineren Fall von 1+ Listen angewendet werden

27voto

jfs Punkte 370717

Version mit reinem Listenverständnis

>>> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
>>> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
>>> c1set = frozenset(c1)

Variante abflachen:

>>> [n for lst in c2 for n in lst if n in c1set]
[13, 32, 7, 13, 28, 1, 6]

Verschachtelte Variante:

>>> [[n for n in lst if n in c1set] for lst in c2]
[[13, 32], [7, 13, 28], [1, 6]]

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X