2012-05-12 13 views
21

Si tengo una función def f(a, b, c, d) y dos tuplas, cada una con dos elementos, ¿hay alguna manera de descomprimir estas tuplas para que pueda enviar sus valores a la función?Cómo desempaquetar varias tuplas en la llamada a función

f(*tup1, *tup2) 
+2

También sentí que esto debería funcionar. Permitir que solo una expresión * y ** expanda argumentos en la función _calls_ parece una restricción innecesaria para mí. Del mismo modo, para permitirlo solo al final de la lista. Esta restricción lleva en la práctica al desorden de códigos de tupla y dictado alrededor de las llamadas a funciones. – Stefan

+1

A partir de [Python 3.5.0] (https://www.python.org/downloads/release/python-350/), gracias a [PEP-448] (http://www.python.org/dev/ peps/pep-0448 /), su psuedocode ahora es válido Python. Ver [mi respuesta actualizada] (http://stackoverflow.com/a/10564819/722121). –

Respuesta

24

A partir de the release of Python 3.5.0, PEP 448 "Additional Unpacking Generalizations" hace que la sintaxis natural para este Python válida:

>>> f(*tup1, *tup2) 
1 2 2 3 

En las versiones anteriores de Python, que puede necesitar para concatenar las tuplas juntos para proporcionar un solo argumento ampliado:

>>> tup1 = 1, 2 
>>> tup2 = 2, 3 
>>> def f(a, b, c, d): 
     print(a, b, c, d) 

>>> f(*tup1+tup2) 
1 2 2 3 
+0

Si tup1 tiene una longitud 4, ¿se ignora tup2? ¿Es ese el comportamiento deseado? – Spacedman

+2

@Spacedman No, 6 valores serían enviados, y obtendría un error (o funcionaría para una función que toma 6 argumentos). –

+0

Correcto, pero si los dos tups se suman a la longitud cuatro funcionará, pero podría ocultar un error sutil. Yo siempre preferiría desempaquetar explícitamente. – Spacedman

-4
f(tup1[0],tup1[1],tup2[0],tup2[1]) #not good enough? 
+6

¿Qué pasa si no sabes la longitud de las tuplas? Además es feo. –

+1

Si las tuplas no tienen longitud 2, ¿qué sucede en la otra solución? Explícito es mejor que implícito? – Spacedman

+2

@Spacedman Esto es tedioso de leer y escribir. –

11

Otro abordaje con chain

>>> from itertools import chain 
>>> def foo(a,b,c,d): 
     print a,b,c,d 


>>> tup1 = (1,2) 
>>> tup2 = (3,4) 
>>> foo(*chain(tup1,tup2)) 
1 2 3 4 
+1

+1. Buena solución, especialmente si tienes muchas tuplas. –

+0

@Lattyware correcto, pero para dos tuplas su solución es la más rápida según mis pruebas. – jamylak

Cuestiones relacionadas