Почему python делает следующее?Странное поведение 2-мерного списка в python
>>> bla = [[]] * 5
>>> bla[3].append("blub")
>>> print bla
[['blub'], ['blub'], ['blub'], ['blub'], ['blub']]
Я ожидал бы
[[], [], [], ['blub'], []]
Почему python делает следующее?Странное поведение 2-мерного списка в python
>>> bla = [[]] * 5
>>> bla[3].append("blub")
>>> print bla
[['blub'], ['blub'], ['blub'], ['blub'], ['blub']]
Я ожидал бы
[[], [], [], ['blub'], []]
Это общая точка путаницы с Python, чтобы сделать с неявной передачи по ссылке , При вводе
x = []
, который связывает имя x
, чтобы указать на пустой список в памяти. Когда вы делаете
x = [[]] * 5
, который связывает имя x
, чтобы указать список из пяти вещей, каждый из которых является ссылкой на пустой список же. Это может быть яснее, если вы думаете об этом так:
>>> y = []
>>> x = [y]*5
>>> x
[[], [], [], [], []]
>>> x[0].append(0)
>>> x
[[0], [0], [0], [0], [0]]
>>> y
[0]
То есть, даже если []
не связывает никаких имен переменных, он по-прежнему создает ссылку на пустой список, который затем копируется в пять раз.
Если вы этого не хотите, вам нужно явно построить пять пустых списков для хранения в x
. Есть различные способы сделать это (copy.deepcopy
общее решение), но я думаю, что опрятная является:
x = [[] for _ in range(5)]
В качестве альтернативы, numpy
является модуль расширения, который обеспечивает очень мощный многомерный массив.
Вы умножая содержимое исходного списка пять раз - это внутренний список просто ссылка, так же ссылка умножаются в пять раз.
Другими словами, у конечного списка есть список, содержащий один и тот же список несколько раз.
Простой способ обойти это для Python 2:
[[] for i in xrange(5)]
Python 3:
[[] for i in range(5)]
`_` (более` i`) рекомендуется, потому что он указывает «Я фактически не использую это» (в то время как `i` часто используется как индекс). – delnan 2010-12-15 15:56:20