2012-12-14 12 views
23

spesso mi ritrovo a fare questo:Python nidificato looping Idiom

for x in range(x_size): 
    for y in range(y_size): 
     for z in range(z_size): 
      pass # do something here 

Esiste un modo più conciso per fare questo in Python? Sto pensando a qualcosa lungo le linee di

for x, z, y in ... ? : 

risposta

38

È possibile utilizzare itertools.product:

>>> for x,y,z in itertools.product(range(2), range(2), range(3)): 
...  print x,y,z 
... 
0 0 0 
0 0 1 
0 0 2 
0 1 0 
0 1 1 
0 1 2 
1 0 0 
1 0 1 
1 0 2 
1 1 0 
1 1 1 
1 1 2 
+0

Grazie. Ho finito per seguire una strada diversa perché non posso usare itertools, ma, dopo aver esaminato la documentazione per itertools, è esattamente ciò di cui avevo bisogno. – cacti

+0

Vale la pena notare che una delle grandi cose di itertools.product è che non sta creando gli elenchi intermedi, il che comporterebbe un sacco di accodamenti e operazioni di ridimensionamento e memoria dell'array dietro le quinte. Quindi questa versione non è solo elegante, ma anche più veloce e molto più facile sul garbage collector! Se il tuo ciclo annidato occupa molto del tuo runtime quando profilato, vale la pena provare questo approccio. –

8

Se hai numpy come una dipendenza già, numpy.ndindex farà il trucco ...

>>> for x,y,z in np.ndindex(2,2,2): 
...  print x,y,z 
... 
0 0 0 
0 0 1 
0 1 0 
0 1 1 
1 0 0 
1 0 1 
1 1 0 
1 1 1 
+0

Hmm ... Apparentemente questo fa la stessa cosa di "itertools.product". Avrei dovuto vederlo arrivare ... :-) – mgilson

+0

Mi piace questa soluzione! È davvero conciso, anche se sarebbe più un idioma "intorpidito" che un idioma python. – Bakuriu

+7

@Bakuriu - Vengo dalla prospettiva che 'python' senza' numpy' è solo un giocattolo lucido ... Ma so che non è la prospettiva di tutti :-). – mgilson

7

Utilizzare itertools.product():

import itertools 
for x, y, z in itertools.product(range(x_size), range(y_size), range(z_size)): 
    pass # do something here 

Dalla documentazione:

prodotto cartesiano di iterables ingresso.

Equivalente a for-loop annidati in un'espressione di generatore.
...

0

Dipende da cosa è all'interno del ciclo. Se si tratta di elenchi, è possibile utilizzare uno list comprehension

Per il caso più generale, vedere this post su itertools.