Получение списков ключей и значений кортежа - PullRequest
0 голосов
/ 15 марта 2011

Я могу понять, zip() функция используется для построения списка кортежей, как это:

x = ['a', 'b', 'c']
y = ['x', 'y', 'z', 'l']
lstTupA = zip(x,y)

lstTupA будет [('a', 'x'), ('b', 'y'), ('c', 'z')].

lstA, lstB = zip(*lstTupA)

Вышеоперация извлекает keys в списке кортежей в lstA и values в списке кортежей в lstB.

lstA было ('a', 'b', 'c'), а lstB было ('x', 'y', 'z').

Мой вопрос таков: почему кортежи lstA и lstB вместо списков?a, b и c однородны, как и x, y и z.Нелогично группировать их как кортежи, не так ли?

В идеале lstA, lstB = zip(*lstTupA) должен был бы назначить ['a', 'b', 'c'] на lstA и ['x', 'y', 'z'] на lstB (списки), верно?

Кто-нибудь, пожалуйста, уточните!

Спасибо.

Ответы [ 6 ]

5 голосов
/ 15 марта 2011

"Нелогично группировать их как кортежи, не так ли?"

Да.Это логично.

Существует два вида встроенных последовательностей.Списки и кортежи.

Функция zip() имеет n аргументов, определяющих количество элементов кортежа, которое должно быть зафиксировано на n .

Список был бы уместен, только если другие аргументы каким-то волшебным образом добавлялись или не добавлялись к результирующей последовательности.Это будет означать последовательности переменной длины, не определенные числом аргументов zip().Это было бы довольно сложной структурой для построения с помощью одного вызова функции.

2 голосов
/ 15 марта 2011

Что *lstTupA делает в lstA, lstB = zip(*lstTupA) (или вообще операторе *) i для выравнивания итерируемого.Таким образом, zip(*lstTupA) равно zip(lstTupA[0], lstTupA[1], ...), и эти элементы являются кортежами, переданными в zip, и именно поэтому lstA и lstB являются кортежами.

2 голосов
/ 15 марта 2011

zip просто определяется, чтобы вести себя так:

In [2]: help(zip)
Help on built-in function zip in module __builtin__:

zip(...)
    zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)]

    --> Return a list of tuples <--, where each tuple contains the i-th element
    from each of the argument sequences.  The returned list is truncated
    in length to the length of the shortest argument sequence.
1 голос
/ 15 марта 2011

В идеале lstA, lstB = zip (* lstTupA) должны были назначить ['a', 'b', 'c'] для lstA и ['x', 'y', 'z'] для lstB(списки) верно?

Нет, это не правильно.Помните, что zip возвращает список кортежей, это именно то, что вы ожидаете, когда он скажет, что

lstTupA будет [('a', 'x'), ('b','y'), ('c', 'z')].

Итак, почему он возвращает что-то другое в случае zip(*lstTupA)?Он по-прежнему возвращает список кортежей, в этом случае [('a', 'b', 'c'), ('x', 'y', 'z')].Выполнив присваивание lstA и lstB, вы просто извлекаете кортежи из списка.

1 голос
/ 15 марта 2011

zip не знает, что находится слева от знака равенства. Насколько известно, lstTupA = zip(x,y) и lstA, lstB = zip(*lstTupA) - это одно и то же. zip определено, чтобы делать что-то одно, и оно постоянно в этом. Вы решили разбить список кортежей во втором операторе, поэтому вы добавляете дополнительный контекст ко второму оператору.

0 голосов
/ 11 мая 2012

Да, вы должны сделать что-то глупое, как

[list(t) for t in zip(*lst)]

Просто чтобы получить списки.

То, что «питонисты» спешат защитить мозговой выбор списков кортежей, не помнят, так это то, что кортежи не могут быть назначены. Что делает zip(*m) бесполезным для матриц или чего-либо еще, где вы хотите изменить элементы позже.

...