82 votes

Pourquoi ne x,y = zip(*zip(a,b)) travail en Python?

OK j'adore Python zip() fonction. L'utiliser tout le temps, c'est génial. Chaque maintenant et encore, je veux faire le contraire de zip(), pense que "j'ai utilisé pour savoir comment le faire", puis google python décompressez, puis rappelez-vous que l'on utilise cette magie * pour décompresser une zippée liste de tuples. Comme ceci:

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)

Ce qui sur terre se passe? Ce qui est magique astérisque? Où d'autre peut-il être appliqué et que d'autres belles choses incroyables en Python sont si mystérieux et difficile à google?

43voto

Daniel Stutzbach Points 20026

L'astérisque en Python est décrite dans le tutoriel Python, sous le Déballage des Listes d'arguments.

18voto

Chris Jester-Young Points 102876

L'astérisque effectue apply (comme il est connu en Lisp et Scheme). Fondamentalement, il faut que votre liste, et appelle la fonction avec la liste du contenu en tant qu'arguments.

9voto

bcherry Points 3541

Il est également utile pour plusieurs arguments:

def foo(*args):
  print args

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

# also legal
t = (1, 2, 3)
foo(*t) # (1, 2, 3)

Et, vous pouvez utiliser l'astérisque double pour le mot-clé arguments et les dictionnaires:

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}

Et bien sûr, vous pouvez combiner ces:

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

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

Très soigné et des trucs utiles.

6voto

BenAnhalt Points 21

Il ne fonctionne pas toujours:

>>> 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

Oups! Je pense qu'il a besoin d'un crâne à l'effrayer en travail:

>>> unzipped_x, unzipped_y = zip(*zipped) or ([], [])
>>> unzipped_x
[]
>>> unzipped_y
[]

En python3, je pense que vous avez besoin

>>> unzipped_x, unzipped_y = tuple(zip(*zipped)) or ([], [])

depuis zip retourne maintenant un générateur de fonction qui n'est pas Faux-y.

0voto

Evgeni Sergeev Points 1517

Additif à @bcherry de réponse:

>>> def f(a2,a1):
...  print a2, a1
... 
>>> d = {'a1': 111, 'a2': 222}
>>> f(**d)
222 111

De sorte qu'il fonctionne non seulement avec le mot-clé arguments (dans ce sens strict), mais avec des arguments nommés trop (aka position arguments).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X