Python -Schnittmenge mehrerer Listen?

Lesezeit: 4 Minuten

Python Schnittmenge mehrerer Listen
Legende

Ich spiele mit Python und kann den Schnittpunkt zweier Listen erhalten:

result = set(a).intersection(b)

Wenn jetzt d ist eine Liste mit a und b und ein drittes Element cgibt es eine eingebaute Funktion, um die Schnittmenge aller drei darin enthaltenen Listen zu finden d? Also zum Beispiel

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

dann sollte das Ergebnis sein

[3,4]

set.intersection(*map(set,d))

  • Nicht sicher, was hier falsch ist. Jetzt gibt es mir: TypeError: intersection() takes exactly one argument (2 given)

    – Legende

    4. Oktober 10 um 4:20 Uhr


  • Vielen Dank. +1 dafür. Ich konnte es wegen meiner Python-Version einfach nicht verwenden 🙁

    – Legende

    4. Oktober 10 um 4:47 Uhr

  • Wenn die d Variable darf die Länge Null haben set.intersection Funktion wird a erhöhen TypeError Ausnahme. Ich würde empfehlen, diese Ausnahme abzufangen und zurückzukehren set() (eine leere Menge) stattdessen in diesem degenerierten Fall. Dies ist besser als die Überprüfung der len von d vorher, da es sich um einen Generator handeln kann.

    – Aaron Robson

    26. September 12 um 23:51 Uhr


  • @AaronR: Guter Punkt, aber die entartete Lösung für die Schnittmenge ist die universelle Menge, nicht die leere Menge. Da es in Python keine kompakte Möglichkeit gibt, dies darzustellen, ist das Auslösen einer Ausnahme (wahrscheinlich das Abfangen des Typfehlers und das Auslösen von etwas Vernünftigerem) wahrscheinlich immer noch der richtige Weg, um damit umzugehen. Zurückgeben einer leeren Menge ist das Richtige für set union, jedoch.

    – SingleNegationElimination

    27. September 12 um 5:36 Uhr

  • @TokenMacGuy: Ja, du hast recht; in Analogie zu en.wikipedia.org/wiki/Empty_product es wäre die einzige Menge, die das Ergebnis einer Schnittmenge garantiert nicht ändert.

    – Aaron Robson

    28. September 12 um 19:59 Uhr


Python Schnittmenge mehrerer Listen
aaronasterling

für 2.4 können Sie einfach eine Schnittfunktion definieren.

def intersect(*d):
    sets = iter(map(set, d))
    result = sets.next()
    for s in sets:
        result = result.intersection(s)
    return result

für neuere Versionen von Python:

Die Schnittpunktmethode nimmt eine beliebige Anzahl von Argumenten an

result = set(d[0]).intersection(*d[1:])

Alternativ können Sie den ersten Satz mit sich selbst schneiden, um ein Aufteilen der Liste und das Erstellen einer Kopie zu vermeiden:

result = set(d[0]).intersection(*d)

Ich bin mir nicht sicher, was effizienter wäre, und habe das Gefühl, dass es von der Größe des Geräts abhängen würde d[0] und die Größe der Liste, es sei denn, Python hat eine eingebaute Prüfung dafür wie

if s1 is s2:
    return s1

im Schnittverfahren.

>>> d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]
>>> set(d[0]).intersection(*d)
set([3, 4])
>>> set(d[0]).intersection(*d[1:])
set([3, 4])
>>> 

  • @AaronMcSmooth: Es gibt mir AttributeError: 'list' object has no attribute 'intersection' wenn ich das mache. Übersehe ich etwas?

    – Legende

    4. Oktober 10 um 4:19 Uhr

  • @Legende. Sie müssen es zuerst einem Set zuordnen. Ich habe irgendwie übersehen, dass es sich um Listen handelt. Danach können Sie einfach Listen (oder andere iterierbare) an die übergeben intersection Methode

    – Aaronasterling

    4. Oktober 10 um 4:20 Uhr


  • @AaronMcSmooth: Eigentlich nicht sicher warum, aber ich erhalte diesen Fehler, egal welche Lösung ich versuche: TypeError: intersection() takes exactly one argument (3 given)

    – Legende

    4. Oktober 10 um 4:24 Uhr

  • @Legende. Sowohl meine Antwort als auch TokenMacGuys Arbeit für mich auf Python 2.6 und 3.1

    – Aaronasterling

    4. Oktober 10 um 4:26 Uhr

  • @Legende. Danke für die Bereinigung meines Posts. aber denke daran: „So sprach der Herr: „Du sollst vier Zwischenräume einrücken. Nicht mehr und nicht weniger. Vier Zwischenräume sollst du einrücken, und die Zahl deiner Einrückungen soll vier sein. Acht sollst du nicht einrücken, auch nicht zwei einrücken, außer dass du dann zu vier weitergehst. Tabs sind des Teufels Äpfel!“

    – Aaronasterling

    4. Oktober 10 um 4:51 Uhr

@ user3917838

Schön und einfach, aber es muss etwas gecastet werden, damit es funktioniert und als Ergebnis eine Liste erstellt wird. Es sollte so aussehen:

list(reduce(set.intersection, [set(item) for item in d ]))

wo:

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

Und Ergebnis ist:

[3, 4]

Zumindest in Python 3.4

1643951767 650 Python Schnittmenge mehrerer Listen
A.John Callegari

Sie können den Schnittpunkt beliebiger Zahlenmengen mit erhalten set.intersection(set1, set2, set3...). Sie müssen also nur Ihre Listen in Sets umwandeln und sie dann wie folgt an diese Methode übergeben:

d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]  
set.intersection(*[set(x) for x in d])  

Ergebnis:

{3, 4}

Lambda reduzieren.

from functools import reduce #you won't need this in Python 2
l=[[1, 2, 3, 4], [2, 3, 4], [3, 4, 5, 6, 7]]
reduce(set.intersection, [set(l_) for l_ in l])

  • Sie benötigen eine Liste von set , dies würde nicht sagen, dass ‘Deskriptorschnittmenge set erfordert’

    – tj89

    20. September 17 um 6:08 Uhr

1643951767 160 Python Schnittmenge mehrerer Listen
mirekphd

ich finde reduce() besonders nützlich sein. Tatsächlich ist die numpy Dokumente empfehlen die Verwendung reduce() um mehrere Listen zu schneiden: numpy.intersect1d-Referenz

Zur Beantwortung Ihrer Frage:

import numpy as np
from functools import reduce
# apply intersect1d to (a list of) multiple lists:
reduce(np.intersect1d, [list_1, list_2, ... list_n])

  • Sie benötigen eine Liste von set , dies würde nicht sagen, dass ‘Deskriptorschnittmenge set erfordert’

    – tj89

    20. September 17 um 6:08 Uhr

.

764940cookie-checkPython -Schnittmenge mehrerer Listen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy