Python
Python3

スター表現(starred expressions)で可変長パックできるって本当ですか?

チート級にすごいpythonのスター表現を利用したパック、アンパックのテク
cookbookに普通に載ってるんだけど、これ本自体が古めで日本語化もだいぶ遅れたから知らない/読んでない人も多いと思う。でも実際読む価値は非常に高いと思う。というわけで論よりなんたら。

>>> record
('FREEDOM', 'DEPARTURES', 'FEEL LIKE DANCE', '1', '2', '3')
>>> song1, song2, song3 , *num = record
>>> song1
'FREEDOM'
>>> song2
'DEPARTURES'
>>> song3
'FEEL LIKE DANCE'
>>> num
['1', '2', '3']
>>> *songname, *num = record
SyntaxError: two starred expressions in assignment
>>> *songname, num1, num2, num3 = record
>>> songname
['FREEDOM', 'DEPARTURES', 'FEEL LIKE DANCE']
>>> num1
'1'
>>> num3
'3'

はい。これはソースコードのすべてです。コレ以外に何も書かなくともこれと同じ挙動になります。すごーい!!!
これを応用した形で

records = [
     ('foo', 1, 2),
     ('bar', 'hello'),
     ('foo', 3, 4),
]

def do_foo(x, y):
    print('foo', x, y)

def do_bar(s):
    print('bar', s)

for tag, *args in records:
    if tag == 'foo':
        do_foo(*args)
    elif tag == 'bar':
        do_bar(*args)

注目すべきはdo_fooとdo_barはそれぞれ引数の数が違う、それでも*argsを使って同じように引数を渡すことができる。スター表現っていうのは単純なアンパックだけでなく、イテラブルから可変長パッキングできるってのが一番すごいところ。この書き方マスターできればさらにソースコードが読み易くすっきりする。。

pythonのシーケンス型へのこだわりは異常(誉め言葉)

余談

>>> RECORD
['text', 'text1', 'mojiretsu', '1', '2', '4']
>>> *chaseq, num1, num2, num3 = RECORD
>>> chaseq
['text', 'text1', 'mojiretsu']
>>> RECORD
['text', 'text1', 'mojiretsu', '1', '2', '4']
>>> RECORD[0] = 'GENESIS OF NEXT'
>>> RECORD
['GENESIS OF NEXT', 'text1', 'mojiretsu', '1', '2', '4']
>>> chaseq
['text', 'text1', 'mojiretsu']