Python: я не могу понять концепцию For Loop, по-видимому - PullRequest
2 голосов
/ 24 октября 2010

У меня есть список из 400 чисел, и я хочу добавить их в сетку 20x20, используя Python.

Я создал «2d массив» (на самом деле не потому, что Python их не поддерживает, мне пришлось использовать список списков).

Когда я пытаюсь выполнить цикл и назначить каждый последующий элемент следующему блоку в сетке, происходит сбой. я заканчиваю тем, что добавляю последний элемент в список к каждой коробке.

Вот код:

numbers = "08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48"
grid = [[0 for col in range(20)] for row in range(20)]

for x in range(0, 1200, 3):
    y = x + 2
    a = numbers[x:y]
    for i in range(20):
        for j in range(20):
            grid[i][j] = a

print(grid)

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

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

Проблема в том, что я не могу понять, где именно.

Кто-нибудь подаст мне руку?

Ответы [ 3 ]

6 голосов
/ 24 октября 2010

Это та вещь, для которой хорошо подходят списочные представления.

nums = iter(numbers.split())
grid = [[next(nums) for col in range(20)] for row in range(20)]

В качестве альтернативы в виде цикла for:

grid = [[0]*20 for row in range(20)]
nums = iter(numbers.split())
for i in xrange(20):
    for j in xrange(20):
        grid[i][j] = next(nums)

Я не рекомендую вамсделать это, но способ сделать это, если вы не хотите просто разделить список и затем вызвать next на своем итераторе, это написать генератор для анализа списка таким же образом, как вы, а затем вызвать next натот.Я подчеркиваю это, потому что есть ситуации, когда встроенные команды не будут делать это за вас, поэтому вы должны увидеть шаблон (не шаблон дизайна, просто шаблон для педантичного):

def items(numbers):
    for x in range(0, len(numbers), 3):
        yield numbers[x:x+2]

 nums = items(numbers)
 for i in xrange(20):
     for j in xrange(20):
         grid[i][j] = next(nums)

Это позволяет вам пройти через два циклав параллели.

5 голосов
/ 24 октября 2010

Другой альтернативой является использование идиомы grouper :

nums = iter(numbers.split())
grid = zip(*[nums]*20)

Обратите внимание, что это список кортежей , а не список списков . Если вам нужен список списков, то

grid = map(list,zip(*[nums]*20))
3 голосов
/ 24 октября 2010

Ваша путаница для цикла связана с тем, что в ней больше циклов, чем вам нужно.

Вместо этого, один из подходов состоит в том, чтобы начать с зацикливания квадратов сетки, а затем вычислить необходимое смещение в списке чисел:

for i in range(20):
  for j in range(20):
    offset = i*20*3 + j*3
    grid[i][j] = numbers[offset:offset+2]

В этом случае смещение имеет несколько констант.i - это строка, поэтому для каждой строки необходимо пропустить количество символов в строке (60) в вашем списке.j - индекс столбца;каждый столбец имеет ширину 3 символа.

Конечно, вы можете выполнить эту операцию в обратном порядке.В этом случае вы перебираете список чисел и затем выясняете, к какому квадрату сетки он принадлежит.Он работает очень похожим образом, за исключением того, что вы будете использовать деление и арифметику по модулю вместо умножения в приведенном выше смещении.

Надеюсь, это даст некоторое представление о том, как использовать циклы для работы с несколькими объектами и несколькими измерениями.1012 *

...