การขยาย tuples เป็นอาร์กิวเมนต์


411

มีวิธีในการขยาย Python tuple เป็นฟังก์ชัน - เป็นพารามิเตอร์จริงหรือไม่?

ตัวอย่างเช่น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)ทำสิ่งที่คุณร้องขอ *ผู้ประกอบการเพียง unpacks tuple ที่ (หรือ iterable ใด ๆ ) และผ่านพวกเขาเป็นข้อโต้แย้งตำแหน่งไปยังฟังก์ชัน อ่านเพิ่มเติมเกี่ยวกับข้อโต้แย้งการเปิดออก


8
ตัวดำเนินการ * เพียงปลด tuple และส่งผ่านเป็นอาร์กิวเมนต์ตำแหน่งไปยังฟังก์ชัน ดูเพิ่มเติมได้ที่นี่: docs.python.org/3/tutorial/…
john_mc

4
โปรดทราบว่าไวยากรณ์เดียวกันสามารถใช้กับรายการเช่นเดียวกับ tuples
brendon-ai

ฉันพบว่าคุณสามารถทำสิ่งเดียวกันกับรายการ (อันที่จริงแล้วสามารถทำซ้ำได้รวมถึงสตริง) แต่ไม่แน่ใจว่าความไม่แน่นอนของการเปลี่ยนแปลงมีผลต่อสิ่งต่าง ๆ อย่างไร นั่นจะน่าสนใจที่จะดู
wcyn

52

โปรดทราบว่าคุณสามารถขยายรายการอาร์กิวเมนต์บางส่วนได้:

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

13
ดูเหมือนว่าคุณสามารถทำสิ่งนี้ได้หาก tuple ที่ขยายเพิ่มนั้นอยู่หลังการขัดแย้งที่ได้รับตามปกติ - ล่ามไม่ชอบเมื่อฉันทำสิ่งนี้:some_func(*tuple_of_stuff, another_argument)
Tom Galvin

6
@Quackmatic การมี tuple ที่ขยายในตำแหน่งใด ๆ ดูเหมือนว่าจะทำงานได้ดีใน Python 3.5.1
River

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 มันพูดถึงการส่ง tuples เป็นอาร์กิวเมนต์

ฉันจะพิจารณาใช้พารามิเตอร์ที่มีชื่อ (และส่งต่อพจนานุกรม) แทนที่จะใช้ tuple และส่งต่อเนื่อง ฉันพบว่าการใช้อาร์กิวเมนต์ตำแหน่งเป็นการปฏิบัติที่ไม่ดีเมื่อตำแหน่งไม่ง่ายหรือมีหลายพารามิเตอร์


8

นี่คือวิธีการเขียนโปรแกรมการทำงาน มันยกคุณสมบัติการขยายตัวของ tuple จากไวยากรณ์น้ำตาล:

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 และสิ่งนี้มีประโยชน์สำหรับฉัน นี่คือวิธีการทำงานที่บริสุทธิ์ หากคุณไม่ได้ใช้สไตล์นี้คำตอบนี้ไม่เหมาะสำหรับคุณ
Dominykas Mostauskis

1
Toolz เป็นบุคคลที่สามคือสิ่งที่ผมหมายถึง
gberger

5
ไม่ใช่ทุกคำตอบที่จะต้องมีสำหรับผู้เริ่มต้น
Jordan

1
สำหรับตัวอย่างที่คุณให้ไว้หนึ่งสามารถใช้starmap docs.python.org/3.7/library/itertools.html#itertools.starmap
Bo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.