Memperluas tuple menjadi argumen

411

Apakah ada cara untuk memperluas tupel Python ke fungsi - sebagai parameter aktual?

Sebagai contoh, inilah expand()keajaibannya:

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

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

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

Aku tahu satu bisa mendefinisikan myfunsebagai myfun((a, b, c)), tapi tentu saja mungkin ada kode warisan. Terima kasih

AkiRoss
sumber

Jawaban:

734

myfun(*some_tuple)melakukan persis apa yang Anda minta. The *Operator hanya membongkar tupel (atau iterable) dan melewati mereka sebagai argumen posisi ke fungsi. Baca lebih lanjut tentang membongkar argumen .

Alex Martelli
sumber
8
Operator * hanya membongkar tuple dan meneruskannya sebagai argumen posisi ke fungsi. Lihat lebih lanjut di sini: docs.python.org/3/tutorial/…
john_mc
4
Perhatikan bahwa sintaks yang sama dapat digunakan untuk daftar dan juga tupel.
brendon-ai
Saya telah menemukan bahwa Anda dapat melakukan hal yang sama dengan daftar, (pada kenyataannya, setiap iterable, termasuk string), tidak yakin bagaimana mutabilitas mereka mempengaruhi sesuatu. Itu akan menarik untuk dilihat.
wcyn
52

Perhatikan bahwa Anda juga dapat memperluas bagian dari daftar argumen:

myfun(1, *("foo", "bar"))
Valentas
sumber
13
Tampaknya Anda hanya dapat melakukan ini jika tuple yang diperluas adalah setelah argumen yang biasanya disediakan - penerjemah tidak menyukainya ketika saya melakukan ini:some_func(*tuple_of_stuff, another_argument)
Tom Galvin
6
@ Quackmatic Memiliki tuple yang diperluas di lokasi mana pun tampaknya bekerja dengan baik di Python 3.5.1
River
1
@Quackmatic seconding @River, ini berfungsi dengan baik di Python 3.5.4: def func(a,b,c,d): print(a,b,c,d)denganargs = ('fee', 'fi', 'fo'); func(*args, 'fum')
R. Navega
15

Lihatlah bagian tutorial Python 4.7.3 dan 4.7.4. Ini berbicara tentang melewati tupel sebagai argumen.

Saya juga akan mempertimbangkan menggunakan parameter bernama (dan melewati kamus) daripada menggunakan tuple dan melewati urutan. Saya menemukan penggunaan argumen posisi menjadi praktik yang buruk ketika posisi tidak intuitif atau ada beberapa parameter.

Uri
sumber
8

Ini adalah metode pemrograman fungsional. Ini mengangkat fitur ekspansi tuple dari gula sintaks:

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

Contoh penggunaan:

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'

kari redefinisi apply_tuplemenghemat banyak partialpanggilan dalam jangka panjang.

Dominykas Mostauskis
sumber
5
Ini tidak membantu bagi pemula. Ia menggunakan modul pihak ketiga dan melakukan hal-hal membingungkan lainnya ...
gberger
gberger, lambda f, t: f(*t)tidak menggunakan modul pihak ketiga dan saya pemula Python dan ini membantu saya. Ini adalah pendekatan fungsional murni. Jika Anda tidak menggunakan gaya ini maka jawaban ini bukan untuk Anda.
Dominykas Mostauskis
1
toolz adalah pihak ketiga, itulah yang saya maksud
gberger
5
Tidak setiap jawaban harus ditujukan untuk seorang pemula
Jordan
1
Untuk contoh yang Anda berikan, seseorang dapat menggunakan starmap docs.python.org/3.7/library/itertools.html#itertools.starmap
Bo.