Как функции for и enumerate работают вместе в этом вложенном цикле над содержимым 2D-массива?

#python

#python

Вопрос:

Я каким-то образом понимаю, как работает перечисление, и я знаю, как работают циклы for . Я просто в основном не понимаю плитки и плитки и как это работает

 for row, tiles in enumerate(self.map_data):
    for col, tile in enumerate(tiles):
        if tile == "1":
        Wall(self. col, row)
  

Итак, предполагается, что это займет map.txt файл с кучей 1 «s», представляющих стены, и 0 «s», представляющих пустое пространство. Этот код проходит через все эти области и размещает то, что должно быть там соответственно, следуя этому видео.

Комментарии:

1. print( list( enumerate(self.map_data) )) и вы увидите, что у вас есть.

2. карта содержит строки и столбцы. Первая for получает одну строку из карты с номером ее строки, вторая for получает одну ячейку из строки с номером ее столбца.

3. Я понимаю, что он выводит свой номер индекса целой строкой. Как он находит единицы и .’ы и разделяет их?

4. Так что, по-видимому, мой разум, похоже, думает, что row и col означают что-то кодовое.. Пока я не заменил их на cow и dol, и он все еще работал. Это просто смутило меня еще больше.

5. row , и col являются нормальными переменными, а enumerate присваивает им значения 0, 1,2,3 и т. Д. Вы можете вызывать их cow или dol , но хорошо иметь имена, которые объясняют, что у вас есть в переменной. В row у вас будет номер строки, в col у вас будет column's number — вы также можете назвать его x, y

Ответ №1:

enumerate возвращает 2 элемента (за итерацию) — индекс (от 0 до n) и сами элементы (упорядоченные).

Итак, это тот случай, который вы приводите:

 for row, tiles in enumerate(self.map_data):
    for col, tile in enumerate(tiles):
        if tile == "1":
        Wall(self, col, row)
  

map_data это 2D-массив листов, содержащий строки и столбцы.
В первом enumerate вы получаете номер строки (вызывается row здесь ) и саму строку (которая представляет собой 1D массив листов, вызываемых tiles здесь ). Затем второй enumerate перебирает этот 1D-массив тайлов (вызывается tiles ) и получает индекс (который является столбцами) и сам элемент, который является тайлом (вызывается tile ).

Вы могли бы концептуально переписать это примерно так, что могло бы быть более понятным:

 for i, map_data[i] in enumerate(map_data):
    for j, map_data[i,j] in enumerate(map_data[i]):
        tile = map_data[i,j]
        if tile == "1":
        Wall(self, col, row)
  

Я не знаю контекста, но замечаю, что ==1 относится к самому элементу, а не к индексу, поэтому в этом случае tile, вероятно, кодируется так, что 1 обозначает наличие стены.

редактировать: я заметил в исходном коде, который вы используете self. , но я предполагаю, что это опечатка, и я написал self, здесь .

редактировать 2: я надеюсь, что этот пример поможет, используя список строк, который, по-видимому, является данными, которые у вас есть. предположим, у вас есть

 map_data = ['1111','1001','1101','1111']
  

первый цикл выдаст 0,1,2,3 for row , а затем '1111', 1001','1101','1111' for tiles . Затем второй цикл выдаст 0,1,2,3 for col и '1','1','1','1' for tile для первой строки (где row равно 0 и tiles равно '1111' ), 0,1,2,3 а '1','0','0','1' для второй строки ( '1001' ) и т.д.

Комментарии:

1. Теперь я понимаю первый цикл for, просто не могу понять второй.

2. Второй выполняется для строк, поскольку каждая строка представляет собой одномерный массив, вы можете снова запустить цикл через него, и каждый элемент является плиткой. Поможет ли вам пример с числами?

3. Итак, я напечатал на экране как данные карты, так и фрагменты, в Map data перечислены строки с их индексом и каждый отдельный символ в этой строке. (0, «111111111111111111111»), листы перечисляют (1, «1») 30 раз, что, по-видимому, составляет всего 1 строку, разделенную на ее элементы. Является ли второй цикл for просто повторением этого для каждой отдельной строки?

4. Я не уверен, что вы показываете, но это похоже на первую строку (возможно, край экрана?) это все стены. Я бы не стал хранить map_data таким образом, но кажется, что это список строк, и когда вы выполняете итерацию по строке (например, с enumerate ), он будет проходить по каждому символу (поэтому «11111» будет обрабатываться так же, как [1,1,1,1,1]). Надеюсь, теперь это проясняет ситуацию.

5. Это просто невероятно сбивает меня с толку. Я не уверен, что я просто глуп, но, похоже, я не могу этого понять. Я благодарю вас за вашу помощь.