我使用了一个列表 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([[1,2,3],[4,5,6]])
。如果有*
,你执行的是zip([1,2,3],[4,5,6])
。
*
运算符用于在函数调用语句中展开参数。def add(x, y):
return x + y
*
字符被称为解包运算符。当它出现在可迭代对象的后面时,它会将可迭代对象内部的项目逐个传递给函数调用者。 在这种情况下,由于zip
函数接受一个可迭代对象列表以按顺序返回其对齐的列,zip(*p)
将p
内所有项目作为参数传递给zip
函数:
因此,在这种情况下,zip(*p)
等同于:
zip([1,2,3],[4,5,6])
另外请注意,自 Python-3.5 起,你可以在一些情况下使用打包操作符(unpacking operator),而不仅仅是函数调用。其中之一被称为“就地解包”(in-place unpacking),它允许你在另一个可迭代对象中使用解包。
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]
x = [1,2,3]
,调用f(x)
时,x接收到一个参数[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时,您想要将[1,2,3]与[4,5,6]进行压缩,因此您需要传递两个参数给zip,因此需要使用星号运算符。如果没有它,您只传递一个参数。
*
或 **
的函数 定义 是使用 *
运算符的不同用法,就像你提到的那样。在这种情况下,它用于创建可变参数函数。它们与 OP 所说的 *
有关,后者更像是 apply
运算符的语法糖。混淆它们是个坏主意。 - Noufal Ibrahim虽然这不是你所问的答案,但它应该会有所帮助。由于zip用于组合两个列表,因此您应该执行类似于list(zip(p[0], p[1]))
的操作来实现您所期望的结果。
*
,这是我读过的最好的解释。谢谢。 - Antoine Colson