2009-06-09 14 views
24

J'ai créé un tableau multidimensionnel en Python comme ceci:Itère un tableau multidimensionnel en Python

self.cells = np.empty((r,c),dtype=np.object) 

Maintenant, je veux itérer tous les éléments de mon tableau à deux dimensions, et je ne se soucient pas de l'ordre. Comment puis-je y parvenir?

Répondre

38

Il est clair que vous utilisez numpy. Avec numpy vous pouvez simplement faire:

for cell in self.cells.flat: 
    do_somethin(cell) 
+1

Je pense qu'il existe maintenant un moyen plus efficace de le faire avec ['numpy.nditer()'] (https://docs.scipy.org/doc/numpy/reference/generated/numpy.nditer.html) – tuned

13

Juste itérer sur une dimension, puis l'autre.

for row in self.cells: 
    for cell in row: 
     do_something(cell) 

Bien sûr, avec seulement deux dimensions, vous pouvez compresser cela à une seule boucle en utilisant une expression list comprehension ou un générateur, mais ce n'est pas très évolutive ou lisible:

for cell in (cell for row in self.cells for cell in row): 
    do_something(cell) 

Si vous devez mettre à l'échelle cela à plusieurs dimensions et que vous voulez vraiment une liste à plat, vous pouvez write a flatten function.

+1

Vous vous êtes trompé. Cela devrait être: pour cellule dans [cellule pour ligne dans self.cells pour cellule dans ligne]: do_something (cellule) – xApple

+0

Wow, cette réponse est ancienne. Tu as raison; réparera. – Eevee

+0

N'est-ce pas la façon dont il l'a bien fait? C'est juste une expression de générateur au lieu d'une compréhension de liste ... est-ce que je manque quelque chose? O.o –

4

Que diriez-vous ceci:

import itertools 
for cell in itertools.chain(*self.cells): 
    cell.drawCell(surface, posx, posy) 
+0

' itertools.chain.from_iterable (self.cells) ' – jfs

26

Si vous devez modifier les valeurs des cellules individuelles puis ndenumerate (en numpy) est votre ami. Même si vous ne le faites pas, c'est probablement le cas!

for index,value in ndenumerate(self.cells): 
    do_something(value) 
    self.cells[index] = new_value 
6

vous pouvez obtenir l'index de chaque élément, ainsi que l'élément lui-même en utilisant la commande énumérer:

for (i,row) in enumerate(cells): 
    for (j,value) in enumerate(row): 
    print i,j,value 

i, j contiennent la ligne et l'indice colonne de l'élément et value est l'élément lui-même .

2

Personne n'a une réponse qui fonctionnera sous forme arbitraire de dimensions sans numpy, donc je vais mettre ici une solution récursive que je l'ai utilisé

def iterThrough(lists): 
    if not hasattr(lists[0], '__iter__'): 
    for val in lists: 
     yield val 
    else: 
    for l in lists: 
     for val in iterThrough(l): 
     yield val 

for val in iterThrough(
    [[[111,112,113],[121,122,123],[131,132,133]], 
    [[211,212,213],[221,222,223],[231,232,233]], 
    [[311,312,313],[321,322,323],[331,332,333]]]): 
    print(val) 
    # 111 
    # 112 
    # 113 
    # 121 
    # .. 

Cela n'a pas très bon, mais la vérification des erreurs cela fonctionne pour moi