Что продолжается здесь? Повторение строк в случайном списке списков

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

from pprint import pprint
from random import random

nrows, ncols = 5, 5
grid = [[0] * ncols] * nrows
for r in range(nrows):
    for c in range(ncols):
        grid[r][c] = int(random() * 100)
pprint(grid)

Пример произвел:

[[64, 82, 90, 69, 36],
 [64, 82, 90, 69, 36],
 [64, 82, 90, 69, 36],
 [64, 82, 90, 69, 36],
 [64, 82, 90, 69, 36]]
1
задан Jesse Aldridge 14 June 2010 в 00:29
поделиться

1 ответ

Я думаю, это потому, что python использует слабую копию списка, когда вы вызываете

grid = [...] * nrows

. Я пытался жестко кодировать список, и он работал правильно:

>>> grid = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]]
>>> for r in range(nrows):
...     for c in range(ncols):
...             grid[r][c] = int(random() * 100)
... 
>>> pprint(grid)
[[67, 40, 41, 50, 92],
 [26, 42, 64, 77, 77],
 [65, 67, 88, 77, 76],
 [36, 21, 41, 29, 25],
 [98, 77, 38, 40, 96]]

Это говорит мне, что когда python копирует список 5 раз, все он сохраняет 5 указателей на ваш первый список - затем, когда вы меняете значения в этом списке, вы фактически просто меняете значение в первом списке, и оно отражается во всех списках, которые указывают на этот.

Используя ваш метод, вы не можете обновить весь список самостоятельно.

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

grid = [[0] * ncols for row in range(ncols)]

Это должно создать для вас 5 независимых списков.

2
ответ дан 2 September 2019 в 23:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: