Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python zip(列表)和zip(*列表)之间的差异_Python_Python 3.x - Fatal编程技术网

Python zip(列表)和zip(*列表)之间的差异

Python zip(列表)和zip(*列表)之间的差异,python,python-3.x,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)] 我发现在列表名之前添加一个“*”可以提供我所需的输出,但我无法区分它们的操作。你能解释一下区别吗?虽然这不是

我正在使用一个列表
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)]

我发现在列表名之前添加一个“*”可以提供我所需的输出,但我无法区分它们的操作。你能解释一下区别吗?

虽然这不是你所问问题的答案,但应该会有所帮助。由于zip用于组合两个列表,因此您应该执行类似于以下的操作来完成预期的操作。

zip
希望将一组参数压缩在一起,但您只有一个参数(列表,其元素也是列表)。函数调用中的
*
将列表(或其他iterable)“解包”,使其每个元素成为单独的参数。因此,如果没有
*
,您就在做
zip([[1,2,3],[4,5,6]])
。使用
*
,您正在执行
zip([1,2,3],[4,5,6])
简而言之,使用
x=[1,2,3]
,调用
f(x)
时,x接收1个参数
[1,2,3]
。使用星形运算符
f(*x)
时,f接收三个参数,它相当于调用
f(1,2,3)

这就是为什么在Python文档中,您经常会看到
一些函数(*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个参数传递给zip,因此您需要一个星形运算符。没有它,您只传递一个参数。

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

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

zip([1,2,3],[4,5,6])
另外,请注意,由于Python-3.5,您可以在函数调用程序之外的一些其他情况下使用解包运算符。其中之一称为就地解包,允许您在另一个iTable中使用解包

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]

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

想想这个

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

运算符“*”创建列表并将其应用于函数。该函数获取n个列表,并从两个列表中的每个元素创建n元组对:

zip([iterable,…])

此函数返回元组列表,其中第i个元组包含 每个参数序列或iterables的第i个元素。这个 返回的列表的长度被截断为最短列表的长度 参数序列。当有多个参数都是 相同的长度,zip()类似于map(),初始参数为 没有一个对于单个序列参数,它返回一个1元组列表。 如果没有参数,它将返回一个空列表


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

像您提到的那样使用
*
***
的函数定义是
*
操作符的不同用法。在这种情况下,它用于创建。它们与OP所说的
*
有关,后者更像是
apply
操作符的语法糖。混淆两者是个坏主意。我认为它们是同一概念的两个方面(尽管行为不同)。在一种情况下(函数定义),指定函数将接受在一个名称(args)下分组的多个参数,而在另一种情况下,将一个名称分派给多个参数。当然,它们是不同的,但它们是紧密相连的语法概念,理解其中一个会让你理解另一个。就像我说的,它们是相关的,但考虑到提问者缺乏这方面的专业知识,这会让人困惑,而不是指导。这很公平。希望他能进一步挖掘。我读过的关于解包操作员的最好解释
*
。非常感谢。