for python zip

for - sorted python



¿Por qué x, y=zip(* zip(a, b)) funcionan en Python? (6)

OK, me encanta la función zip() Python. Úselo todo el tiempo, es brillante. De vez en cuando quiero hacer lo contrario de zip() , pensar "Yo solía saber cómo hacer eso", entonces google python descomprimir, luego recordar que uno usa este mágico * para descomprimir una lista comprimida de tuplas. Me gusta esto:

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)

¿Qué diablos está pasando? ¿Qué está haciendo ese asterisco mágico? ¿Dónde más se puede aplicar y qué otras cosas increíbles en Python son tan misteriosas y difíciles de buscar en Google?


Adición a la respuesta de @ bcherry:

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

Por lo tanto, funciona no solo con argumentos de palabras clave (en este sentido estricto ), sino también con argumentos con nombre (también conocidos como argumentos posicionales ).



El asterisco se apply (como se lo conoce en Lisp y Scheme). Básicamente, toma su lista y llama a la función con el contenido de esa lista como argumentos.


No siempre funciona:

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

Oops! Creo que necesita un cráneo para asustarlo para que funcione:

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

En python3 creo que necesitas

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

ya que zip ahora devuelve una función de generador que no es False-y.


Soy extremadamente nuevo en Python, por lo que esto me acabó de hacer caer, pero tenía que ver más con cómo se presentaba el ejemplo y qué se hacía hincapié.

Lo que me dio problemas para entender el ejemplo zip fue la asimetría en el manejo del valor (s) de devolución de llamada zip. Es decir, cuando se llama a zip la primera vez, el valor de retorno se asigna a una sola variable, creando así una referencia de lista (que contiene la lista de tuplas creada). En la segunda convocatoria, aprovecha la capacidad de Python para desempaquetar automáticamente un valor de retorno de la lista (¿o de la colección?) En múltiples referencias de variables, siendo cada referencia la tupla individual. Si alguien no está familiarizado con la forma en que funciona en Python, es más fácil perderse en lo que está sucediendo realmente.

>>> x = [1, 2, 3] >>> y = "abc" >>> zipped = zip(x, y) >>> zipped [(1, ''a''), (2, ''b''), (3, ''c'')] >>> z1, z2, z3 = zip(x, y) >>> z1 (1, ''a'') >>> z2 (2, ''b'') >>> z3 (3, ''c'') >>> rezipped = zip(*zipped) >>> rezipped [(1, 2, 3), (''a'', ''b'', ''c'')] >>> rezipped2 = zip(z1, z2, z3) >>> rezipped == rezipped2 True


También es útil para múltiples argumentos:

def foo(*args): print args foo(1, 2, 3) # (1, 2, 3) # also legal t = (1, 2, 3) foo(*t) # (1, 2, 3)

Y, puedes usar asterisco doble para los argumentos y diccionarios de las palabras clave:

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}

Y por supuesto, puedes combinar estos:

def foo(*args, **kwargs): print args, kwargs foo(1, 2, a=3, b=4) # (1, 2) {''a'': 3, ''b'': 4}

Bastante limpio y útil.