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


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.