Ich habe eine Liste von Listen und eine Trennzeichenfolge wie diese:

lists = [
    ['a', 'b'],
    [1, 2],
    ['i', 'ii'],
]
separator = '-'

Als Ergebnis möchte ich eine Liste von Zeichenfolgen mit einer Trennzeichenfolge aus den Zeichenfolgen in den Unterlisten kombinieren:

result = [
    'a-1-i', 
    'a-1-ii', 
    'a-2-i', 
    'a-2-ii',
    'b-1-i', 
    'b-1-ii', 
    'b-2-i', 
    'b-2-ii',
]

Die Reihenfolge im Ergebnis ist irrelevant.

Wie kann ich das machen?

12
Martin 9 Okt. 2012 im 11:23

4 Antworten

Beste Antwort
from itertools import product
result = [separator.join(map(str,x)) for x in product(*lists)]

itertools.product gibt einen Iterator zurück, der das kartesische Produkt der bereitgestellten Iterablen erzeugt. Wir müssen map str über die resultierenden Tupel setzen, da einige der Werte Ints sind. Schließlich können wir die stringifizierten Tupel verbinden und das Ganze in ein Listenverständnis werfen (oder einen Generatorausdruck, wenn es sich um einen großen Datensatz handelt und Sie ihn nur für die Iteration benötigen).

16
jpm 9 Okt. 2012 im 07:45
["%s%c%s%c%s" % (a, separator, b, separator, c) for a in lists[0] for b in lists[1] for c in lists[2]]
1
user434817user434817 9 Okt. 2012 im 07:32
>>> from itertools import product
>>> result = list(product(*lists))
>>> result = [separator.join(map(str, r)) for r in result]
>>> result
['a-1-i', 'a-1-ii', 'a-2-i', 'a-2-ii', 'b-1-i', 'b-1-ii', 'b-2-i', 'b-2-ii']

Wie @jpm hervorhob, müssen Sie list nicht wirklich in den product Generator umwandeln. Ich hatte diese, um die Ergebnisse in meiner Konsole zu sehen, aber sie werden hier nicht wirklich benötigt.

3
K Z 9 Okt. 2012 im 07:43

Sie können dies mit eingebauten Funktionen tun:

>>> map(separator.join, reduce(lambda c,n: [a+[str(b)] for b in n for a in c], lists, [[]]))
['a-1-i', 'b-1-i', 'a-2-i', 'b-2-i', 'a-1-ii', 'b-1-ii', 'a-2-ii', 'b-2-ii']
3
Benedict 9 Okt. 2012 im 11:46