Как распаковать несколько кортежей при вызове функции

Если у меня есть функцияdef f(a, b, c, d) и два кортежа, каждый с двумя элементами, есть ли способ распаковать эти кортежи, чтобы я мог отправить их значения в функцию?

<code>f(*tup1, *tup2)
</code>
 Stefan04 окт. 2012 г., 14:13
Я также чувствовал, что это должно работать. Разрешить только одно выражение * и ** для расширения аргументов в функции Звонки кажется мне ненужным ограничением. Точно так же разрешить это только в конце списка. Это ограничение на практике приводит к тому, что код, создающий кортежи и диктовки, мешает вызовам функций.
 Gareth Latty14 сент. 2015 г., 14:18
Как изPython 3.5.0, благодаря PEP-448, ваш psuedocode теперь является действительным Python. Видеть мой обновленный ответ.

Ответы на вопрос(3)

Решение Вопроса

Как из выпуск Python 3.5.0, PEP 448 "Дополнительные обобщения распаковки" делает естественный синтаксис для этого допустимого Python:

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

В старых версиях Python вам может понадобиться объединить кортежи вместе, чтобы предоставить один расширенный аргумент:

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

>>> f(*tup1+tup2)
1 2 2 3
 Gareth Latty12 мая 2012 г., 17:08
@ Spacedman Нет, 6 значений будут отправлены, и вы получите ошибку (или она будет работать для функции, которая принимает 6 аргументов).
 Spacedman12 мая 2012 г., 17:07
Если tup1 имеет длину 4, то tup2 игнорируется? Это желаемое поведение?
 Gareth Latty12 мая 2012 г., 17:45
Я думаю, что это ближе всего к псевдо-коду, который задал аскер. Он хотел получить способ распаковать все значения из двух кортежей - это поведение, которое дает мой ответ. Хотя есть потенциальные ошибки, они есть во всех методах, и это скорее вопрос дизайна программ
 Spacedman12 мая 2012 г., 17:13
Правильно, но если две пары сложить до длины четыре, это сработает, но могущественно замаскирует небольшую ошибку. Я всегда предпочел бы явно распаковать.

Другой подход с использованием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
 jamylak12 мая 2012 г., 17:18
@ Lattyware правильно, но для двух кортежей, согласно моим тестам, ваше решение самое быстрое.
 Gareth Latty12 мая 2012 г., 17:03
+ 1. Хорошее решение, особенно если у вас много кортежей.
f(tup1[0],tup1[1],tup2[0],tup2[1]) #not good enough?
 Spacedman12 мая 2012 г., 17:04
Если кортежи не имеют длины 2, что происходит в другом решении? Явное лучше, чем неявное?
 Gareth Latty12 мая 2012 г., 17:01
А если ты не знаешь длины кортежей? Плюс это некрасиво.
 Paul Manta12 мая 2012 г., 17:06
@ Spacedman Это утомительно читать и писать.
 Gareth Latty12 мая 2012 г., 17:09
Я бы сказал, что игнорирование лишних значений хуже, чем исключения, которые вы получаете в другом месте.
 Spacedman12 мая 2012 г., 17:15
Для моего решения ошибка, которая является правильным поведением (операционная система говорит «два кортежа длины два»). Для упаковочных решений, тихого бега, тонких ошибок ...

Ваш ответ на вопрос