#python #python_3x #python_faq
Вот код a = [[0]*3]*3 counter = 0 for x in range(3): for y in range(3): print('At x=%d y=%d was appended %d' % (x, y, counter)) a[x][y] = counter counter += 1 print(a) Не могу понять в чем ошибка, вроде должен заполнять от 1 до 9, но в выводе получаю [[6, 7, 8], [6, 7, 8], [6, 7, 8]]. Добавил print() в цикле, показывает нормальное заполнение Подскажите, где ошибка?
Ответы
Ответ 1
В вашем примере создается список ссылок на один и тот же список. Попробуйте создавать список a таким образом: a = [ [0]*3 for i in range(3) ] Ну и counter стартовать с 1. Можно еще так (при условии, что под массивом понимается список списков): args = [ iter(range(1, 10)) ] * 3 l = [ list(t) for t in list(zip(*args)) ]Ответ 2
from itertools import count as count_from count = count_from(1) matrix = [[next(count) for _ in range(3)] for _ in range(3)] Получаем: [[1, 2, 3], [4, 5, 6], [7, 8, 9]] [L]*3 создаёт список: [L, L, L], то есть все элементы ссылаются на один и тот же объект (Что значит * (звёздочка) и ** двойная звёздочка в Питоне?). Если L неизменяем, например число, то не имеет значения один объект или несколько используются. Но если L изменяем, как к примеру список в вашем случае, то ваш код a[x][y] = counter изменяет один и тот же список, поэтому все ряды становятся равными последнему ряду (так как каждый ряд представлен одним и тем же списком). Другими словами: [0]*3 можно использовать. [[0]*3]*3 не стоит использовать, а следует заменить на [[0]*3 for _ in range(3)].Ответ 3
Вложенные списки это один объект. Нужно что то вроде этого: a = [[0 for _ in range(3)] for _ in range(3)]Ответ 4
Можно еще таким способом: >>> result = [[j for j in range(i-2, i+1)] for i in range(3, 10, 3)] >>> result [[1, 2, 3], [4, 5, 6], [7, 8, 9]] Или так: >>> list(map(lambda x: list(range(x-2, x+1)), range(3, 10, 3))) [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Комментариев нет:
Отправить комментарий