Frage

Ich mag das folgende Idiom verwenden, um Listen zusammen kombiniert, manchmal:

>>> list(itertools.chain(*[[(e, n) for e in l] for n, l in (('a', [1,2]),('b',[3,4]))]))
[(1, 'a'), (2, 'a'), (3, 'b'), (4, 'b')]

(ich weiß, es gibt einfachere Wege, um dieses bestimmtes Ergebnis zu bekommen, aber es kommt ist praktisch, wenn Sie über die Elemente in Listen von Listen von Listen zu durchlaufen wollen, oder so ähnlich. Das Problem ist, wenn Sie Generator verwenden Ausdrücke, dies wird fehleranfällig. Eg

>>> list(itertools.chain(*(((e, n) for e in l) for n, l in (('a', [1,2]),('b',[3,4])))))
[(1, 'b'), (2, 'b'), (3, 'b'), (4, 'b')]

Was hier passiert, ist, dass die inneren Generator Ausdrücke übergeben bekommen als Argumente an itertools.chain, so bei der die Zeit, die sie ausgewertet sind, hat der äußere Generator Ausdruck abgeschlossen, und n an seinem Endwert, 'b' fixiert. Ich frage mich, ob jemand hat Möglichkeiten gedacht, diese Art von Fehler zu vermeiden, darüber hinaus „tun das nicht.“

War es hilfreich?

Lösung

Ihr Ansatz fast funktioniert, brauchen Sie nur die Generatoren zu glätten. Sehen Sie, wie die for e in l bis ganz nach rechts bewegt wird,

>>> list(itertools.chain((e, n) for n, l in (('a', [1,2]),('b',[3,4])) for e in l ))
[(1, 'a'), (2, 'a'), (3, 'b'), (4, 'b')]

Hier ist, wie die gleiche Sache zu tun mit itertools.product

>>> X=itertools.chain(*(itertools.product(*i[::-1]) for i in (('a', [1,2]),('b',[3,4]))))
>>> print list(X)
[(1, 'a'), (2, 'a'), (3, 'b'), (4, 'b')]

oder wenn Sie berechtigt sind, die Tupel um

wechseln
>>> X=itertools.chain(*(itertools.product(*i) for i in (([1,2],'a'),([3,4],'b'))))
>>> print list(X)
[(1, 'a'), (2, 'a'), (3, 'b'), (4, 'b')]

Andere Tipps

würde nicht ein verschachtelte Liste Verständnis besser geeignet sein?

>>> tt = (('a', [1,2]),('b',[3,4]))
>>> [(s, i) for i, l in tt for s in l]
[(1, 'a'), (2, 'a'), (3, 'b'), (4, 'b')]

Ich werde vorschlagen

data = (('a', [1,2]), ('b', [3,4]))

result = []
for letter, numbers in data:
     for number in numbers:
         result.append((number, letter))

Es ist viel besser lesbar als Ihre Lösung Familie. Fancy ist nicht eine gute Sache.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top