Возможный дубликат:
Проблема с списком Python
Я пытаюсь инициализировать матрицу в python. Сначала я сделал это:
>>> M=[[0]*4]*4
Но вот моя проблема, каждая строка меняется, когда я меняю первый:
>>> M
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
>>> M[1][1]=1
>>> M
[[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]]
Итак, я сделал это так:
>>> M= [ [ 0 for i in range(4) ] for j in range(4) ]
И ut отлично работает:
>>> M
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
>>> M[1][1]=1
>>> M
[[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Мой вопрос:
Что означают эти два выражения? и почему первый из них ведет себя таким образом?
Заранее благодарим за помощь.
Скажите a
- это некоторый объект python. Тогда [a] * 4
эквивалентно [a, a, a, a]. Что это означает, зависит от того, является ли a
изменчивым или нет. Номера, строки и кортежи не являются, поэтому, если a
является одним из таких объектов (0
в вашем примере), вы получаете 4 независимо изменяемые копии. Списки, словари и наборы изменяемы, и в этом случае вы просто получаете 4 ссылки на один и тот же объект, в вашем случае список [0] * 4
. Используя эти знания, вы увидите, что вы можете сделать это:
M = [[0] * 4 for i in range(4)]
и получите то, что вы хотите.
При умножении этих списков Python копирует их по ссылке, а не создает совершенно новые объекты.
Простой пример может помочь, показывая, что происходит с копией по ссылке:
>>> pie = ['apple', 'cherry', 'pecan']
>>> pie_copy = pie
>>> pie_copy[0] = 'banana'
>>> pie
['banana', 'cherry', 'pecan']
>>> pie is pie_copy
True
>>> new_pie = ['banana', 'cherry', 'pecan']
>>> pie is new_pie
False
Точно так же, как pie_copy и pie указывают на один и тот же список, при создании списков путем умножения все копии указывают на один и тот же список.
В своем втором фрагменте, использующем range()
и понимающем список, вы не берете ни одного списка и не копируете его несколько раз; каждая итерация в понимании создает новый список, поэтому вы не страдаете от той же копии по задаче справки.
Потому что здесь M=[[0]*4]*4
Вы создаете ссылки на объекты.
Это похоже на
>>> a = [0, 0, 0]
>>> b = [a,a,a]
>>> b
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[1] = 1
>>> b
[[0, 1, 0], [0, 1, 0], [0, 1, 0]]
>>>
Ссылки UPD Я имел в виду ссылки, извините, если немного запутать