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


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)), але, звичайно, може бути застарілий код. Дякую

Відповіді:


733

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
Рівер

1
@Quackmatic seconding @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

Погляньте на підручник Python, розділи 4.7.3 та 4.7.4. Це говорить про передачу кортежів як аргументів.

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


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'

каррі- редефінітон apply_tupleрятує багато partialдзвінків у довгостроковій перспективі.


5
Це не корисно для початківця. Він використовує сторонні модулі та робить інші заплутані речі ...
gberger

gberger, lambda f, t: f(*t)не використовує сторонні модулі, і я початківець Python, і це мені корисно. Це чисто функціональний підхід. Якщо ви не використовуєте цей стиль, то ця відповідь не для вас.
Домінікас Мостаскіс

1
що я мав на увазі
toolz

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.