Расширяя кортежи в аргументы


411

Есть ли способ расширить кортеж Python в функцию - в качестве фактических параметров?

Например, вот expand()волшебство:

some_tuple = (1, "foo", "bar")

def myfun(number, str1, str2):
    return (number * 2, str1 + str2, str2 + str1)

myfun(expand(some_tuple)) # (2, "foobar", "barfoo")

Я знаю, что можно определить myfunкак myfun((a, b, c)), но, конечно, может быть устаревший код. Спасибо

Ответы:


734

myfun(*some_tuple)делает именно то, что вы просите. *Оператор просто распаковывает кортеж (или любую итерацию) и передает их в качестве позиционных аргументов функции. Узнайте больше о распаковке аргументов .


8
Оператор * просто распаковывает кортеж и передает его в качестве позиционных аргументов функции. Подробнее здесь: docs.python.org/3/tutorial/…
john_mc

4
Обратите внимание, что один и тот же синтаксис может использоваться как для списков, так и для кортежей.
brendon-ai

Я обнаружил, что вы можете сделать то же самое со списками (фактически любой итерируемой, включая строки), не зная, как их изменчивость влияет на вещи. Это было бы интересно посмотреть.
wcyn

52

Обратите внимание, что вы также можете расширить часть списка аргументов:

myfun(1, *("foo", "bar"))

13
Похоже, что вы можете сделать это только в том случае, если расширенный кортеж следует за обычно предоставленными аргументами - интерпретатору не нравится, когда я делаю это:some_func(*tuple_of_stuff, another_argument)
Том Галвин,

6
@Quackmatic Наличие расширенного кортежа в любом месте прекрасно работает в Python 3.5.1
River

1
@ Quackmatic secondding @River, это прекрасно работает в Python 3.5.4: def func(a,b,c,d): print(a,b,c,d)сargs = ('fee', 'fi', 'fo'); func(*args, 'fum')
R. Navega

15

Взгляните на разделы 4.7.3 и 4.7.4 учебника по Python . Это говорит о передаче кортежей в качестве аргументов.

Я также хотел бы рассмотреть использование именованных параметров (и передачу словаря) вместо использования кортежа и передачи последовательности. Я считаю использование позиционных аргументов плохой практикой, когда позиции не интуитивны или есть несколько параметров.


8

Это метод функционального программирования. Он поднимает функцию расширения кортежа из синтаксического сахара:

apply_tuple = lambda f, t: f(*t)

Пример использования:

from toolz import * 
from operator import add, eq

apply_tuple = curry(apply_tuple)

thread_last(
    [(1,2), (3,4)],
    (map, apply_tuple(add)),
    list,
    (eq, [3, 7])
)
# Prints 'True'

Карри redefiniton из apply_tupleэкономит много partialзвонков в долгосрочной перспективе.


5
Это не полезно для начинающего. Он использует сторонние модули и делает другие запутанные вещи ...
gberger

gberger, lambda f, t: f(*t)не использует сторонние модули, я новичок в Python, и это полезно для меня. Это чисто функциональный подход. Если вы не используете этот стиль, тогда этот ответ не для вас.
Доминикас Мостаускис

1
Toolz является сторонним, вот что я имел в виду
gberger

5
Не каждый ответ должен быть для начинающего
Джордан

1
Для приведенного вами примера можно использовать starmap docs.python.org/3.7/library/itertools.html#itertools.starmap
Bo.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.