Используйте python для зацикливания двух списков, используя один в качестве индекса для списка списков, а другой в качестве значения для добавления - PullRequest
2 голосов
/ 18 марта 2012

У меня проблемы с получением ожидаемых результатов из команды zip. Случаи 1-3 имеют смысл, но в случаях 4 и 5 (которые я предполагаю эквивалентны?) Я ожидаю, что результаты будут [['a'], ['b'], ['c'], ['d' ]], но вместо этого весь второй список добавляется к каждому подсписку списка списков, которые я инициализирую.

Дело 1:

>>> for a in zip([1,2,3,4],['a','b','c','d']):
...     print a

(1, 'a')
(2, 'b')
(3, 'c')
(4, 'd')

Случай 2:

>>> for (a,b) in zip([1,2,3,4],['a','b','c','d']):
...     print a,b
... 
1 a
2 b
3 c
4 d

Дело 3:

>>> temp = [[]] * 4
>>> for (a,b) in zip([0,1,2,3],['a','b','c','d']):
...     temp[a] = b
... 
>>> temp
['a', 'b', 'c', 'd']

Дело 4:

>>> temp = [[]] * 4
>>> for (a,b) in zip([0,1,2,3],['a','b','c','d']):
...     temp[a].append(b)
... 
>>> temp
[['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd']]

Дело 5:

>>> temp = [[]] * 4
>>> for a,b in zip([0,1,2,3],['a','b','c','d']):
...     temp[a].append(b)
... 
>>> temp
[['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'd']]

Ответы [ 4 ]

3 голосов
/ 18 марта 2012

[[]] * 4 создает список ссылок на один объект:

>>> l = [[]] * 4
>>> l
[[], [], [], []]
>>> l[0].append(1)
>>> l
[[1], [1], [1], [1]]

Попробуйте [[] for _ in range(4)].

1 голос
/ 18 марта 2012

Вы столкнулись с тем, как Python работает с именами переменных и ссылками.Это может сбивать с толку, если вы раньше работали с языками в стиле C, но имеет большой смысл, если вы так не думаете!

В Python есть «вещи» и «имена для вещей».Например, x - это имя, [] - это вещь, а x=[] присваивает имя x вещи [].

Синтаксис умножения списка немного запутан в отношениина имена и вещи.Давайте расширим его, чтобы посмотреть, как он работает:

name = [x]*4

- это то же самое, что и

_temp = x
name = [_temp, _temp, _temp, _temp]

. С учетом этого следующий код должен иметь смысл:

>>> x = []
>>> y = [x]*4
>>> y[0].append(1)
>>> y
[[1], [1], [1], [1]]

Почему?Хорошо, когда вы пишете y=[x]*4], вы составляете список из четырех имен.Но это все имена того же существа!Если вы .append(1) на объект, названный по имени, вы измените объект, который все имена, ну, имя.

Теперь, как и раньше,

name = [[]]*4

совпадает с

_temp = []
name = [_temp, _temp, _temp, _temp]

Вы явно не создали новое имя.Но вы сделали это неявно !Вы звоните [] только один раз, поэтому вы создаете только один новый список.Затем вы составляете список из четырех имен, каждое из которых вы только что создали.Поэтому неудивительно, что все имена называют одно и то же!


Как это исправить, говорите вы?Ну, вам нужно позвонить [] один раз для каждого нового списка, который вы хотите.Чтобы сделать это, используйте понимание списка:

[[] for _ in range(4)]

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

1 голос
/ 18 марта 2012
temp = [[]] * 4

Создает список, содержащий четыре ссылки на один и тот же объект списка . У вас есть только один «подсписок», который содержится в «основном списке» четыре раза. Это та же самая ситуация, что и в этом примере:

>>> ls = []
>>> tmp = [ls, ls, ls, ls]
>>> ls.append(1)
>>> tmp
[[1], [1], [1], [1]]

Вы, вероятно, хотели использовать отдельные объекты списка для элементов списка. Такой список можно создать, например, так:

tmp = [[] for _ in range(4)]
0 голосов
/ 18 марта 2012

Это потому, что когда вы создаете temp = [[]] * 4, вы создаете список с 4 ссылками на один и тот же (пустой) список.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...