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

时间:2015-03-19 07:44:46

标签: python python-3.x

我使用的是列表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)]

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

6 个答案:

答案 0 :(得分:42)

zip希望将一堆参数压缩在一起,但你拥有的是一个参数(一个列表,其元素也是列表)。函数调用中的*"解包"列表(或其他可迭代的),使其每个元素成为单独的参数。因此,如果没有*,您就会zip( [[1,2,3],[4,5,6]] )。使用*,您正在zip([1,2,3], [4,5,6])

答案 1 :(得分:9)

*运算符在函数调用语句中解包参数。

考虑一下

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])并获得预期的输出。

答案 2 :(得分:7)

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

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

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

另外,请注意,自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]

答案 3 :(得分:1)

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

答案 4 :(得分:0)

简而言之,使用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时,实际上你想用[4,5,6]压缩[1,2,3],所以你想将2个args传递给zip,因此你需要一个星形运算符。没有它,你只会传递一个参数。

答案 5 :(得分:0)

" *" operator unpacks一个列表并将其应用于函数。 zip函数接受n个列表,并从两个列表中的每个元素创建n元组对:

  

zip([iterable,...])

     

此函数返回元组列表,其中包含第i个元组   来自每个参数序列或迭代的第i个元素。该   返回的列表的长度被截断为最短的长度   论证序列。当有多个参数都是   相同的长度,zip()类似于map(),其初始参数为   没有。使用单个序列参数,它返回一个1元组的列表。   没有参数,它返回一个空列表。

基本上,将*[[1,2,3],[4,5,6]]一起使用,您将[1,2,3][4,5,6]作为参数传递给zip。