Ich habe eine Liste mit 15 Zahlen und muss Code schreiben, der alle 32.768 Kombinationen dieser Zahlen erzeugt.
Ich habe einen Code (von Googling) gefunden, der anscheinend das tut, wonach ich suche, aber ich fand den Code ziemlich undurchsichtig und bin vorsichtig, ihn zu verwenden. Außerdem habe ich das Gefühl, dass es eine elegantere Lösung geben muss.
Das einzige, was mir einfällt, ist, einfach die Dezimalzahlen 1–32768 zu durchlaufen und diese in Binärzahlen umzuwandeln und die Binärdarstellung als Filter zu verwenden, um die entsprechenden Zahlen auszuwählen.
Kennt jemand einen besseren Weg? Verwenden Sie map()
vielleicht?
python
combinations
Ben
quelle
quelle
product
usw.)Antworten:
Schauen Sie sich itertools.combinations an :
Seit 2.6 sind Batterien enthalten!
quelle
list(itertools.combinations(iterable, r))
r
, dh Kombinationen von Längenuntersequenzen von Elementen.Diese Antwort hat einen Aspekt übersehen: Das OP hat nach ALLEN Kombinationen gefragt ... nicht nur nach Kombinationen der Länge "r".
Sie müssten also entweder alle Längen "L" durchlaufen:
Oder - wenn Sie schick werden möchten (oder das Gehirn desjenigen biegen möchten, der Ihren Code nach Ihnen liest) - können Sie die Kette der "Kombinationen ()" - Generatoren generieren und diese durchlaufen:
quelle
powerset()
Generatorfunktion im Abschnitt "Rezepte" deritertools
Dokumentation ist einfacher, benötigt möglicherweise weniger Speicher und ist wahrscheinlich schneller als die hier gezeigte Implementierung.itertools.combinations
die Artikelreihenfolge in den Listen erhalten bleibt. Wenn also die Eingabe lexikalisch sortiert ist, ist auch jede der Ausgaben.itertools.combinations
erzeugt die Kombinationen von k unter n in lexikographischer Reihenfolge, aber nicht alle Kombinationen bis zu k unter n.powerset
erzeugt alle Kombinationen bis k, aber meines Wissens nicht in lexikographischer Reihenfolge: Powerset ([1,2]) -> [(), (1,), (2,), (1, 2)] . Sollte es nicht sein: [(), (1,), (1, 2), (2,)]?Hier ist ein fauler Einzeiler, der auch itertools verwendet:
Hauptidee hinter dieser Antwort: Es gibt 2 ^ N Kombinationen - genau wie die Anzahl der Binärzeichenfolgen der Länge N. Für jede Binärzeichenfolge wählen Sie alle Elemente aus, die einer "1" entsprechen.
Dinge, die man beachten muss:
len(...)
aufitems
(Abhilfe: Wennitems
so etwas wie ein iterable wie ein Generator ist, schalten Sie ihn in eine Liste zuerst mititems=list(_itemsArg)
)items
nicht zufällig ist (Problemumgehung: Seien Sie nicht verrückt).{2,2,1}
und{2,1,1}
wird sowohl Zusammenbruch{2,1}
(Abhilfe: Verwendungcollections.Counter
als Drop-in - Ersatz fürset
, es ist im Grunde ein multiset ... wenn Sie zu den späteren Gebrauch benötigen ,tuple(sorted(Counter(...).elements()))
wenn Sie es brauchen , um hashable)Demo
quelle
In Kommentaren unter der hoch bewerteten Antwort von @Dan H wird das
powerset()
Rezept in deritertools
Dokumentation erwähnt - einschließlich eines von Dan selbst . Doch bisher niemand hat es als Antwort gepostet. Da es wahrscheinlich eine der besseren, wenn nicht die beste Herangehensweise an das Problem ist - und von einem anderen Kommentator ein wenig ermutigt wird , wird es unten gezeigt. Die Funktion erzeugt alle eindeutigen Kombinationen der Listenelemente jeder möglichen Länge (einschließlich derjenigen, die Null und alle Elemente enthalten).Hinweis : Wenn das subtil andere Ziel darin besteht, nur Kombinationen eindeutiger Elemente zu erhalten, ändern Sie die Zeile
s = list(iterable)
ins = list(set(iterable))
, um doppelte Elemente zu entfernen. Unabhängig davon, dass die Tatsache, dass dasiterable
letztendlich zu einemlist
Mittel wird, mit Generatoren funktioniert (im Gegensatz zu einigen anderen Antworten).Ausgabe:
quelle
list()
Konvertierung überhaupt?Hier ist eine mit Rekursion:
quelle
new_data = copy.copy(data)
- Diese Zeile istDieser Einzeiler gibt Ihnen alle Kombinationen (zwischen
0
undn
Elementen, wenn die ursprüngliche Liste / Mengen
unterschiedliche Elemente enthält ) und verwendet die native Methodeitertools.combinations
:Python 2
Python 3
Die Ausgabe wird sein:
Probieren Sie es online aus:
http://ideone.com/COghfX
quelle
['b', 'a']
.TypeError: can only concatenate list (not "map") to list
Ich stimme Dan H zu, dass Ben tatsächlich nach allen Kombinationen gefragt hat .
itertools.combinations()
gibt nicht alle Kombinationen an.Ein weiteres Problem ist, wenn die iterierbare Eingabe groß ist, ist es vielleicht besser, einen Generator anstelle von allem in einer Liste zurückzugeben:
quelle
Dies ist ein Ansatz, der leicht auf alle Programmiersprachen übertragen werden kann, die die Rekursion unterstützen (keine itertools, keine Ausbeute, kein Listenverständnis) :
quelle
Mit diesem einfachen Code können Sie alle Kombinationen einer Liste in Python generieren
Ergebnis wäre:
quelle
Ich dachte, ich würde diese Funktion für diejenigen hinzufügen, die eine Antwort suchen, ohne itertools oder andere zusätzliche Bibliotheken zu importieren.
Verwendung des einfachen Ertragsgenerators:
Ausgabe aus dem obigen Verwendungsbeispiel:
quelle
Hier ist noch eine andere Lösung (einzeilig), bei der die
itertools.combinations
Funktion verwendet wird. Hier verwenden wir jedoch ein doppeltes Listenverständnis (im Gegensatz zu einer for-Schleife oder einer Summe):Demo:
quelle
Ausgabe
quelle
Unten finden Sie eine "rekursive Standardantwort", ähnlich der anderen ähnlichen Antwort https://stackoverflow.com/a/23743696/711085 . (Wir müssen uns realistisch nicht darum kümmern, dass der Stapelspeicherplatz knapp wird, da wir auf keinen Fall alle N! -Permutationen verarbeiten können.)
Es besucht nacheinander jedes Element und nimmt es entweder oder verlässt es (wir können die 2 ^ N-Kardinalität von diesem Algorithmus direkt sehen).
Demo:
quelle
Listenverständnis verwenden:
Ausgabe wäre:
quelle
Dieser Code verwendet einen einfachen Algorithmus mit verschachtelten Listen ...
quelle
""
) zu fehlen .Ich weiß, dass es weitaus praktischer ist, itertools zu verwenden, um alle Kombinationen zu erhalten, aber Sie können dies teilweise nur mit Listenverständnis erreichen, wenn Sie dies wünschen, vorausgesetzt, Sie möchten viel codieren
Für Kombinationen von zwei Paaren:
Und für Kombinationen von drei Paaren ist es so einfach:
Das Ergebnis ist identisch mit der Verwendung von itertools.combinations:
quelle
Ohne itertools zu verwenden:
quelle
Hier sind zwei Implementierungen von
itertools.combinations
Eine, die eine Liste zurückgibt
Man gibt einen Generator zurück
Bitte beachten Sie, dass die Bereitstellung einer Hilfsfunktion für diese empfohlen wird, da das Argument prepend statisch ist und sich nicht bei jedem Aufruf ändert
Dies ist ein sehr oberflächlicher Fall, aber besser auf Nummer sicher gehen
quelle
Wie wäre es damit .. verwendet eine Zeichenfolge anstelle von Liste, aber das gleiche .. Zeichenfolge kann wie eine Liste in Python behandelt werden:
quelle
Kombination aus itertools
Vielen Dank
quelle
Ohne
itertools
in Python 3 könnten Sie so etwas tun:wo anfangs
carry = "".
quelle
3 Funktionen:
quelle
Dies ist meine Implementierung
quelle
Sie können auch die Powerset- Funktion aus dem hervorragenden
more_itertools
Paket verwenden.Wir können auch überprüfen, ob es die Anforderungen von OP erfüllt
quelle
quelle
Wenn jemand nach einer umgekehrten Liste sucht, wie ich es war:
quelle
quelle