Wie kann ich das kartesische Produkt (jede mögliche Wertekombination) aus einer Gruppe von Listen erhalten?
Eingang:
somelists = [
[1, 2, 3],
['a', 'b'],
[4, 5]
]
Gewünschte Ausgabe:
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), (2, 'a', 5) ...]
set(cartesian product)
set(inputlist)
Sie alle Ihre Eingabelisten. Nicht auf das Ergebnis.Antworten:
itertools.product
Verfügbar ab Python 2.6.
Welches ist das gleiche wie,
quelle
product()
generiertnitems_in_a_list ** nlists
Elemente im Ergebnis (reduce(mul, map(len, somelists))
). Es gibt keinen Grund zu der Annahme, dass die Ausbeute eines einzelnen Elements nichtO(nlists)
(amortisiert) ist, dh die zeitliche Komplexität ist dieselbe wie für einfache verschachteltefor
Schleifen, z. B. für die Eingabe in der Frage :nlists=3
, Gesamtzahl der Elemente im Ergebnis :3*2*2
, und Jedes Element hatnlists
Elemente (3
in diesem Fall).*
vor Somelisten? Was tut es?quelle
Für Python 2.5 und älter:
Hier ist eine rekursive Version von
product()
(nur eine Illustration):Beispiel:
quelle
args
ihnen Iteratoren sind.mit itertools.product :
quelle
*
vor Somelisten?Ich würde das Listenverständnis verwenden:
quelle
Hier ist ein rekursiver Generator, der keine temporären Listen speichert
Ausgabe:
quelle
def f(): while True: yield 1
wird seine Stapelgröße weiter erhöhen, während wir es durchlaufen?In Python 2.6 und höher können Sie 'itertools.product` verwenden. In älteren Versionen von Python können Sie den folgenden (fast - siehe Dokumentation) äquivalenten Code aus der Dokumentation verwenden , zumindest als Ausgangspunkt:
Das Ergebnis von beiden ist ein Iterator. Wenn Sie also wirklich eine Liste für die weitere Verarbeitung benötigen, verwenden Sie
list(result)
.quelle
Obwohl es bereits viele Antworten gibt, möchte ich einige meiner Gedanken teilen:
Iterativer Ansatz
Rekursiver Ansatz
Lambda-Ansatz
quelle
Rekursiver Ansatz:
Iterativer Ansatz:
quelle
Eine geringfügige Modifikation der obigen rekursiven Generatorlösung in variadischem Geschmack:
Und natürlich ein Wrapper, mit dem es genauso funktioniert wie diese Lösung:
mit einem Kompromiss : Es wird geprüft, ob die Rekursion bei jeder äußeren Schleife unterbrochen werden soll, und ein Gewinn : Keine Ausbeute bei leerem Aufruf, z
product(())
was meiner Meinung nach semantisch korrekter wäre (siehe den Test).Zum Listenverständnis: Die mathematische Definition gilt für eine beliebige Anzahl von Argumenten, während das Listenverständnis nur eine bekannte Anzahl von Argumenten behandeln kann.
quelle
Nur um ein wenig zu dem hinzuzufügen, was bereits gesagt wurde: Wenn Sie Sympy verwenden, können Sie Symbole anstelle von Zeichenfolgen verwenden, was sie mathematisch nützlich macht.
Über Sympy .
quelle
Ich glaube das funktioniert:
quelle
Stonehenge-Ansatz:
Ausgabe:
quelle