Подтвердить что ты не робот

Разница между zip (list) и zip (* list)

Я использую список p = [[1,2,3],[4,5,6]]

Если я это сделаю:

>>>d=zip(p)
>>>list(d)
[([1, 2, 3],), ([4, 5, 6],)]

Хотя, я действительно хочу получить, используя это:

>>>d=zip(*p)
>>>list(d)
[(1, 4), (2, 5), (3, 6)]

Я обнаружил, что добавление "*" перед именем списка дает мой требуемый результат, но я не могу понять разницу в их работе. Не могли бы вы объяснить разницу?

4b9b3361

Ответ 1

zip хочет, чтобы куча аргументов включалась вместе, но у вас есть один аргумент (список, элементы которого также являются списками). * в вызове функции "распаковывает" список (или другой итерабельный), делая каждый из его элементов отдельным аргументом. Итак, без * вы делаете zip( [[1,2,3],[4,5,6]] ). С помощью * вы делаете zip([1,2,3], [4,5,6]).

Ответ 2

Оператор * распаковывает аргументы в операторе вызова функции.

Рассмотрим это

def add(x, y):
   return x + y

если у вас есть список t = [1,2], вы можете сказать add(t[0], t[1]), который излишне подробный, или вы можете "распаковать" t в отдельные аргументы, используя оператор *, например, add(*t).

Это то, что происходит в вашем примере. zip(p) работает как zip([[1,2,3],[4,5,6]]). У Zip есть один аргумент, поэтому он тривиально возвращает его как кортеж.

zip(*p) работает как zip([1,2,3], [4,5,6]). Это похоже на запуск zip(p[0], p[1]), и вы получите ожидаемый результат.

Ответ 3

Хотя это не тот ответ, который вы задали, он должен помочь. Поскольку zip используется для объединения двух списков, вы должны сделать что-то вроде этого list(zip(p[0], p[1])), чтобы выполнить то, что вы ожидаете.

Ответ 4

На самом деле * является оператором распаковки, а поскольку функция zip принимает список итераций, вы можете передать несколько итераций этой функции:

Итак, результатом *p является:

[1,2,3],[4,5,6]

и zip(*p) равно zip([1,2,3],[4,5,6]).

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

>>> zip(*zip(*p))
[(1, 2, 3), (4, 5, 6)]

Вышеприведенная команда распаковывает результат zip(*p), чтобы у вас было:

zip((1, 4), (2, 5), (3, 6))

zip ([итерируемый,...])

Эта функция возвращает список кортежей, где i-й кортеж содержит i-й элемент из каждой из последовательностей аргументов или итераций. Возвращаемый список усекается по длине с длиной кратчайшей последовательности аргументов. Когда есть несколько аргументов, которые имеют одинаковую длину, zip() похож на map() с начальным аргументом None. С одним аргументом последовательности он возвращает список из 1-кортежей. Без аргументов он возвращает пустой список.

Ответ 5

В двух словах, при x = [1,2,3], при вызове f(x) x получает 1 аргумент [1, 2, 3]. Когда вы используете оператор звезды f(*x), f получает три аргумента, это эквивалентно вызову f(1,2,3).

Вот почему в документации Python вы часто видите some_function(*args, **kwargs). Здесь оператор двойной звезды делает то же самое, но для словаря: с d={"some_arg":2, "some_other_arg":3} вызов f(**d) совпадает с f(some_arg=2, some_other_arg=3).

Теперь, когда вы используете zip, вы действительно хотите zip [1,2,3] с [4,5,6], поэтому вы хотите передать 2 аргумента в zip, поэтому вам нужен оператор-звезда. Без этого вы передаете только один аргумент.

Ответ 6

Оператор "*" распаковывает список и применяет его к функции. Функция zip принимает n списков и создает пары n-кортежей из каждого элемента из обоих списков:

zip ([итерируемый,...])

Эта функция возвращает список кортежей, где i-й кортеж содержит i-й элемент из каждой из последовательностей аргументов или итераций. возвращенный список усечен по длине до самой короткой последовательность аргументов. Когда есть несколько аргументов, которые являются такая же длина, zip() аналогична map() с начальным аргументом Никто. С одним аргументом последовательности он возвращает список из 1-кортежей. Без аргументов он возвращает пустой список.

В основном, используя * с [[1,2,3],[4,5,6]], вы передаете [1,2,3] и [4,5,6] в качестве аргументов для zip.