Ich weiß, wie man einen Schnittpunkt zweier flacher 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]
oder
def intersect(a, b):
return list(set(a) & set(b))
print intersect(b1, b2)
Aber wenn ich Schnittpunkte für verschachtelte Listen finden muss, beginnen meine Probleme:
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 möchte ich erhalten:
c3 = [[13,32],[7,13,28],[1,6]]
Könnt ihr mir dabei helfen?
verbunden
python
list
intersection
elfuego1
quelle
quelle
Antworten:
Falls Sie es wollen:
Dann ist hier Ihre Lösung für Python 2:
In Python 3 wird
filter
anstelle von iterable eine iterable zurückgegebenlist
, sodass Siefilter
Aufrufe mitlist()
folgenden Zeilen umschließen müssen :Erläuterung:
Der Filterteil nimmt das Element jeder Unterliste und prüft, ob es in der Quellliste c1 enthalten ist. Das Listenverständnis wird für jede Unterliste in c2 ausgeführt.
quelle
filter(set(c1).__contains__, sublist)
für die Effizienz verwenden. Übrigens besteht der Vorteil dieser Lösung darin, dassfilter()
Zeichenfolgen und Tupeltypen erhalten bleiben.c3 = [[x for x in sublist if x in c1] for sublist in c2]
Sie müssen keine Kreuzung definieren. Es ist bereits ein erstklassiger Teil des Sets.
quelle
set(b1) & set(b2)
? IMO sein Reiniger, um den Bediener zu verwenden.set
zu Code, der um Größenordnungen schneller ist. Hier ist ein Beispiel für einen Benchmark®: gist.github.com/andersonvom/4d7e551b4c0418de3160Für Leute, die nur den Schnittpunkt zweier Listen suchen, hat der Asker zwei Methoden bereitgestellt:
Es gibt jedoch eine Hybridmethode, die effizienter ist, da Sie nur eine Konvertierung zwischen Liste / Satz durchführen müssen, im Gegensatz zu drei:
Dies wird in O (n) ausgeführt, während seine ursprüngliche Methode zum Listenverständnis in O (n ^ 2) ausgeführt wird.
quelle
Der funktionale Ansatz:
und es kann auf den allgemeineren Fall von 1+ Listen angewendet werden
quelle
set(*input_list[:1]).intersection(*input_list[1:])
. Iterator-Version (it = iter(input_list)
) :reduce(set.intersection, it, set(next(it, [])))
. In beiden Versionen müssen nicht alle Eingabelisten zum Festlegen konvertiert werden. Letzteres ist speichereffizienter.from functools import reduce
, um es in Python 3 zu verwenden. Oder verwenden Sie noch besser eine explizitefor
Schleife.Version mit reinem Listenverständnis
Variante abflachen:
Verschachtelte Variante:
quelle
Der Operator & nimmt den Schnittpunkt zweier Mengen.
quelle
Eine pythonische Methode, um den Schnittpunkt zweier Listen zu bestimmen, ist:
quelle
Sie sollten diesen Code reduzieren (entnommen aus http://kogs-www.informatik.uni-hamburg.de/~meine/python_tricks ). Der Code ist nicht getestet, aber ich bin mir ziemlich sicher, dass er funktioniert:
Nachdem Sie die Liste abgeflacht haben, führen Sie die Kreuzung wie folgt aus:
quelle
Da
intersect
definiert wurde, reicht ein grundlegendes Listenverständnis aus:Verbesserung dank der Bemerkung von S. Lott und der damit verbundenen Bemerkung von TM.:
quelle
Gegeben:
Ich finde, dass der folgende Code gut funktioniert und möglicherweise prägnanter ist, wenn die Set-Operation verwendet wird:
Es hat:
Bei Bestellung:
wir haben:
Übrigens, für einen Python-Stil ist auch dieser in Ordnung:
quelle
Ich weiß nicht, ob ich Ihre Frage zu spät beantworte. Nachdem ich Ihre Frage gelesen hatte, kam ich auf eine Funktion intersect (), die sowohl für Listen als auch für verschachtelte Listen geeignet ist. Ich habe Rekursion verwendet, um diese Funktion zu definieren. Sie ist sehr intuitiv. Hoffe es ist was du suchst:
Beispiel:
quelle
Denken Sie darüber
[1,2]
nach, sich zu überschneiden[1, [2]]
? Das heißt, sind es nur die Zahlen, die Sie interessieren, oder auch die Listenstruktur?Wenn nur die Zahlen, untersuchen Sie, wie die Listen "abgeflacht" werden, und verwenden Sie dann die
set()
Methode.quelle
Ich suchte auch nach einer Möglichkeit, dies zu tun, und schließlich endete es so:
quelle
quelle
Wir können hierfür festgelegte Methoden verwenden:
quelle
Um einen Schnittpunkt zu definieren, der die Kardinalität der Elemente korrekt berücksichtigt, verwenden Sie
Counter
:quelle
Hier ist eine Möglichkeit zum Festlegen
c3
, die keine Sätze umfasst:Wenn Sie jedoch nur eine Zeile verwenden möchten, können Sie dies tun:
Es ist ein Listenverständnis innerhalb eines Listenverständnisses, was ein wenig ungewöhnlich ist, aber ich denke, Sie sollten nicht zu viel Mühe haben, ihm zu folgen.
quelle
Für mich ist das ein sehr eleganter und schneller Weg dorthin :)
quelle
flache Liste kann
reduce
leicht durch gemacht werden.Alles was Sie brauchen, um Initialisierer zu verwenden - drittes Argument in der
reduce
Funktion.Der obige Code funktioniert sowohl für Python2 als auch für Python3, Sie müssen jedoch das Reduktionsmodul als importieren
from functools import reduce
. Siehe untenstehenden Link für Details.für python2
für python3
quelle
Einfacher Weg, um Unterschiede und Schnittpunkte zwischen Iterablen zu finden
Verwenden Sie diese Methode, wenn Wiederholung wichtig ist
quelle