为什么x,y = zip(*zip(a,b))在Python中有效?

Mik*_*war 75 python zip

好的我喜欢Python的zip()功能.一直使用它,它很棒.现在每一次我想要做的相反zip(),认为"我以前就知道该怎么做",然后谷歌蟒蛇解压缩,然后记住一个使用这个神奇的*解压缩元组的压缩列表.像这样:

x = [1,2,3]
y = [4,5,6]
zipped = zip(x,y)
unzipped_x, unzipped_y = zip(*zipped)
unzipped_x
    Out[30]: (1, 2, 3)
unzipped_y
    Out[31]: (4, 5, 6)
Run Code Online (Sandbox Code Playgroud)

到底是怎么回事?那个神奇的星号在做什么?还有什么地方可以应用,Python中其他令人惊叹的精彩内容是如此神秘且难以谷歌?

Dan*_*ach 39

Python中的星号记录在Python教程的Unpacking Argument Lists中.


Chr*_*ung 18

星号执行apply(如Lisp和Scheme中所知).基本上,它接受您的列表,并使用该列表的内容作为参数调用该函数.

  • 仅应用存在,因为稍后添加了星号. (2认同)

bch*_*rry 8

它对多个args也很有用:

def foo(*args):
  print args

foo(1, 2, 3) # (1, 2, 3)

# also legal
t = (1, 2, 3)
foo(*t) # (1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

并且,您可以对关键字参数和字典使用双星号:

def foo(**kwargs):
   print kwargs

foo(a=1, b=2) # {'a': 1, 'b': 2}

# also legal
d = {"a": 1, "b": 2}
foo(**d) # {'a': 1, 'b': 2}
Run Code Online (Sandbox Code Playgroud)

当然,你可以结合这些:

def foo(*args, **kwargs):
   print args, kwargs

foo(1, 2, a=3, b=4) # (1, 2) {'a': 3, 'b': 4}
Run Code Online (Sandbox Code Playgroud)

非常整洁有用的东西.


小智 6

它并不总是有效:

>>> x = []
>>> y = []
>>> zipped = zip(x, y)
>>> unzipped_x, unzipped_y = zip(*zipped)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: need more than 0 values to unpack
Run Code Online (Sandbox Code Playgroud)

哎呀!我认为它需要一个头骨来吓唬它工作:

>>> unzipped_x, unzipped_y = zip(*zipped) or ([], [])
>>> unzipped_x
[]
>>> unzipped_y
[]
Run Code Online (Sandbox Code Playgroud)

在python3中,我认为你需要

>>> unzipped_x, unzipped_y = tuple(zip(*zipped)) or ([], [])
Run Code Online (Sandbox Code Playgroud)

因为zip现在返回一个不是False-y的生成器函数.