Итерация по многомерному массиву в Python - PullRequest
26 голосов
/ 09 июня 2009

Я создал многомерный массив в Python следующим образом:

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

Теперь я хочу перебрать все элементы моего двумерного массива, и мне нет дела до порядка. Как мне этого добиться?

Ответы [ 7 ]

39 голосов
/ 09 июня 2009

Понятно, что вы используете NumPy. С NumPy вы можете просто сделать:

for cell in self.cells.flat:
    do_somethin(cell)
28 голосов
/ 06 января 2011

Если вам нужно изменить значения отдельных ячеек, тогда ndenumerate (в numpy) ваш друг. Даже если вы этого не сделаете, вероятно, все еще есть!

for index,value in ndenumerate( self.cells ):
    do_something( value )
    self.cells[index] = new_value
13 голосов
/ 09 июня 2009

Просто переберите одно измерение, затем другое.

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

Конечно, только с двумя измерениями вы можете сжать это до одного цикла, используя список или выражение генератора, но это не очень масштабируемое или читаемое:

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

Если вам нужно масштабировать это до нескольких измерений и вы действительно хотите получить плоский список, вы можете написать flatten функцию .

6 голосов
/ 23 ноября 2015

вы можете получить индекс каждого элемента, а также сам элемент, используя команду enumerate:

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

i, j содержат индекс строки и столбца элемента, а value - сам элемент.

6 голосов
/ 09 июня 2009

Как насчет этого:

import itertools
for cell in itertools.chain(*self.cells):
    cell.drawCell(surface, posx, posy)
4 голосов
/ 07 февраля 2016

Ни у кого нет ответа, который будет работать в произвольном количестве измерений без numpy, поэтому я приведу здесь рекурсивное решение, которое я использовал

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
  # ..

Это не очень хорошая проверка ошибок, но она работает для меня

1 голос
/ 11 октября 2018

Также стоит упомянуть itertools.product().

cells = [[x*y for y in range(5)] for x in range(10)]
for x,y in itertools.product(range(10), range(5)):
    print("(%d, %d) %d" % (x,y,cells[x][y]))

Может создавать декартово произведение произвольного числа итераций:

cells = [[[x*y*z for z in range(3)] for y in range(5)] for x in range(10)]
for x,y,z in itertools.product(range(10), range(5), range(3)):
    print("(%d, %d, %d) %d" % (x,y,z,cells[x][y][z]))
...