enumerate in itertools.product

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
sirdonat
User
Beiträge: 12
Registriert: Dienstag 10. Dezember 2013, 09:14

Hallo,
ich möchte aus 6 Listen alle Möglichen Kombinationen erhalten.
Das ist möglich mit itertools.product

Code: Alles auswählen

for i in itertools.product(x_values, y_values, z_values, xe_values, ye_values, ze_values):
	print i
Ich würde aber gerne noch zusätzlich die Indexwerte aus den Listen mitgeliefert bekommen. Das geht ja mit enumerate.
Mein Code dafür sieht so aus, wobei x0,y0, z0,xe0,ye0 und ze0 die Indexwerte darstellen sollen:

Code: Alles auswählen

(x_values, y_values, z_values, xe_values, ye_values, ze_values) = (numpy.arange(a, b, 8).tolist()for a, b in [(-16, 17), (-8, 57), (-16, 17), (-64, 65), (-16, 17), (-16, 49)])
for x0, y0, z0, xe0, ye0, ze0, i in itertools.product(enumerate(x_values), enumerate(y_values), enumerate(z_values), enumerate(xe_values), enumerate(ye_values), enumerate(ze_values)):
	print i
und ich erhalte folgenden Fehler:
ValueError: need more than 6 values to unpack

Könnt ihr mir helfen, den Syntax richtig zu stellen, falls es möglich ist enumerate mit itertools.product zu kombinieren?
Danke!
BlackJack

@sirdonat: Ich bin jetzt etwas verwirrt was Du da eigentlich als Ergebnis haben möchtest. Was denkst Du denn wird da an `i` gebunden? Probier das doch einfach mal aus:

Code: Alles auswählen

In [22]: (x_values, y_values, z_values, xe_values, ye_values, ze_values) = (numpy.arange(a, b, 8).tolist() for a, b in [(-16, 17), (-8, 57), (-16, 17), (-64, 65), (-16, 17), (-16, 49)])

In [23]: it = itertools.product(enumerate(x_values), enumerate(y_values), enumerate(z_values), enumerate(xe_values), enumerate(ye_values), enumerate(ze_values))
 
In [24]: next(it)
Out[24]: ((0, -16), (0, -8), (0, -16), (0, -64), (0, -16), (0, -16))

In [25]: next(it)
Out[25]: ((0, -16), (0, -8), (0, -16), (0, -64), (0, -16), (1, -8))

In [26]: next(it)
Out[26]: ((0, -16), (0, -8), (0, -16), (0, -64), (0, -16), (2, 0))

In [27]: next(it)
Out[27]: ((0, -16), (0, -8), (0, -16), (0, -64), (0, -16), (3, 8))

In [28]: next(it)
Out[28]: ((0, -16), (0, -8), (0, -16), (0, -64), (0, -16), (4, 16))

In [29]: next(it)
Out[29]: ((0, -16), (0, -8), (0, -16), (0, -64), (0, -16), (5, 24))

In [30]: next(it)
Out[30]: ((0, -16), (0, -8), (0, -16), (0, -64), (0, -16), (6, 32))

In [31]: next(it)
Out[31]: ((0, -16), (0, -8), (0, -16), (0, -64), (0, -16), (7, 40))

In [32]: next(it)
Out[32]: ((0, -16), (0, -8), (0, -16), (0, -64), (0, -16), (8, 48))

In [33]: next(it)
Out[33]: ((0, -16), (0, -8), (0, -16), (0, -64), (1, -8), (0, -16))

In [34]: next(it)
Out[34]: ((0, -16), (0, -8), (0, -16), (0, -64), (1, -8), (1, -8))

In [35]: next(it)
Out[35]: ((0, -16), (0, -8), (0, -16), (0, -64), (1, -8), (2, 0))
Das `arange()` und `to_list()` verstehe ich nicht. Das macht genau das gleiche wie `range()` in diesem Fall. Und wenn Python 2 verwendet wird, dann ist das äquivalent zu `xrange()`, nur das *dafür* dann keine Liste mit Werten erstellt werden muss.
sirdonat
User
Beiträge: 12
Registriert: Dienstag 10. Dezember 2013, 09:14

@BlackJack: Das funktioniert so! Jetzt habe genau das,was ich wollte.
BlackJack hat geschrieben: Das `arange()` und `to_list()` verstehe ich nicht. Das macht genau das gleiche wie `range()` in diesem Fall. Und wenn Python 2 verwendet wird, dann ist das äquivalent zu `xrange()`, nur das *dafür* dann keine Liste mit Werten erstellt werden muss.
Ja, das tolist() macht in der Tat keinen Sinn. Bei langen Listen lohnt es sich schon mit python-list anstatt mit numpy-arrays zu arbeiten, da der Zugriff schneller ist. Kannst du mir aber sagen, wie man hier trotzdem direkt python lists für die ?_values erstellt?
BlackJack

@sirdonat: `range()` erzeugt in Python 2 Listen.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Das kann man jetzt aber auch falsch verstehen :D range erzeugt niemals 2 Listen, nur in der zweiten Version von Python ist es eben genau eine Liste und in der dritten Version ist es ein Generator. Du weißt das, BlackJack, aber ich wollte das nochmal klarstellen, dass es keine Missverständnisse gibt.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@derdon: Wie schon in Python2 »xrange« erzeugt in Python3 »range« ein Range-Objekt, das zum Teil die gleichen Methoden besitzt wie eine Liste. Natürlich verhalten sich Range-Objekte, wie Listen, in manchen Fällen ähnlich wie Generatoren (überall dort, wo ein Iterator erwartet wird).
BlackJack

Weil Korinthenkacken so ein Spass macht: `Range`-Objekte verhalten sich nicht wie Generatoren sondern wie iterierbare Objekte. Der Unterschied? Ein iterierbares Objekt muss selbst kein Iterator sein. Ein Generator ist das aber. :P

Code: Alles auswählen

In [10]: g = (c for c in 'hallo')

In [11]: g
Out[11]: <generator object <genexpr> at 0xa069cac>

In [12]: next(g)
Out[12]: 'h'

In [13]: r = xrange(42)

In [14]: r
Out[14]: xrange(42)

In [15]: next(r)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/home/bj/<ipython-input-15-0b5056469c9c> in <module>()
----> 1 next(r)

TypeError: xrange object is not an iterator

In [16]: r[23]
Out[16]: 23

In [17]: g[3]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/home/bj/<ipython-input-17-9c3f191d55d5> in <module>()
----> 1 g[3]

TypeError: 'generator' object has no attribute '__getitem__'
Antworten