zip(列表)和zip(*list)之间的区别

use*_*438 36 python python-3.x

我正在使用一个列表 p = [[1,2,3],[4,5,6]]

如果我做 :

>>>d=zip(p)
>>>list(d)
[([1, 2, 3],), ([4, 5, 6],)]
Run Code Online (Sandbox Code Playgroud)

虽然,我真正想要的是使用这个:

>>>d=zip(*p)
>>>list(d)
[(1, 4), (2, 5), (3, 6)]
Run Code Online (Sandbox Code Playgroud)

我发现在列表名称之前添加一个'*'给出了我所需的输出,但是我无法弄清楚它们的操作差异.你能解释一下这个区别吗?

Sne*_*tel 47

zip想要将一堆参数压缩在一起,但你拥有的是一个参数(一个列表,其元素也是列表).所述*在一个函数调用"解包"的列表(或其它可迭代),使得它的每个元素的一个单独参数的.所以没有*,你正在做zip( [[1,2,3],[4,5,6]] ).随着*,你正在做zip([1,2,3], [4,5,6]).

  • 我读过关于解包运算符“*”的最好解释。谢谢。 (2认同)

Nou*_*him 10

*运营商解包,函数调用语句的参数.

考虑一下

def add(x, y):
   return x + y
Run Code Online (Sandbox Code Playgroud)

如果你有一个列表t = [1,2],你可以说add(t[0], t[1])哪个是不必要的冗长,或者你可以t使用*运算符"unpack" 到单独的参数中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]),您可以获得预期的输出.


Kas*_*mvd 9

*字符称为拆包运算符。当它出现在可迭代对象的后面时,它所做的就是将可迭代对象中的项目逐一传递给函数的调用者。在这种情况下,由于该zip函数接受可迭代对象的列表以返回其对齐的列,zip(*p)因此请将pas中的所有项作为参数传递给zip函数:

因此,在这种情况下,zip(*p)等于:

zip([1,2,3],[4,5,6])
Run Code Online (Sandbox Code Playgroud)

另外,请注意,从Python-3.5开始,您可以在除函数调用程序之外的其他一些情况下解压缩运算符。其中一种称为就地解包,使您可以在另一个迭代器中使用解包。

In [4]: a = [1, 2, 3]

In [5]: b = [8, 9, *a, 0, 0]

In [6]: b
Out[6]: [8, 9, 1, 2, 3, 0, 0]
Run Code Online (Sandbox Code Playgroud)


ver*_*lon 5

简而言之,x = [1,2,3]当调用 时f(x), x 接收 1 个参数[1, 2, 3]。当使用星号运算符 时f(*x),f 接收三个参数,相当于调用f(1,2,3)

这就是为什么在 Python 的文档中,您经常会看到some_function(*args, **kwargs). 这里双星运算符的作用相同,但对于字典: with d={"some_arg":2, "some_other_arg":3},调用f(**d)与 相同f(some_arg=2, some_other_arg=3)

现在,当您使用 zip 时,实际上您希望将 [1,2,3] 与 [4,5,6] 进行压缩,因此您希望将 2 个参数传递给 zip,因此您需要一个星号运算符。如果没有它,您只能传递一个参数。


tob*_*oef 1

虽然这不是您提出的问题的答案,但它应该有所帮助。由于 zip 用于组合两个列表,因此您应该执行类似的操作list(zip(p[0], p[1]))来完成您的期望。