Python 3: Deep Dive (Part 1 - Functional): *args (セクション5-2/11)
Pythonの拡張アンパッキングは、リストやタプルの要素を柔軟にアンパックし、`*`オペレーターを使用して残りの要素をまとめることができる。
`*args`を使用すると、関数に任意の数の引数を渡し、これらをタプルとして処理できるため、柔軟な関数定義が可能。
リストやタプルの要素をアンパックして関数に引数として渡す方法は、既存のデータ構造を効率的に利用するのに役立つ。
Pythonプログラミングでは、関数はクリーンで再利用可能なコードを書くための基盤です。関数を使用することで、ロジックをカプセル化し、管理がしやすくなり、コードの冗長性が減ります。Pythonの関数の最も強力な機能の一つは、パラメータの扱い方です。このブログ記事では、Python 3: Deep Dive (Part 1 - Functional) コースの第5章(レッスン67〜70)で扱われた2つの主要なトピックである、拡張アンパッキングと関数における`*args`の使用方法について解説します。
Pythonにおける拡張アンパッキング
Python 3.5で導入された拡張アンパッキングは、より柔軟にイテラブルから要素をアンパック(分解)できるようにします。単に位置に基づいて要素を変数に割り当てるだけでなく、`*`オペレーターを使用して残りの要素を1つの変数にまとめることができます。
拡張アンパッキングの基本的な使い方
まずはリストを例に説明します:
l = [1, 2, 3, 4, 5, 6]
a, *b = l
print(a) # 1
print(b) # [2, 3, 4, 5, 6]
この例では、リストの最初の要素(`1`)が`a`にアンパックされ、残りの要素がリストとして`b`に格納されます。
この方法は、リストだけでなく、タプルや文字列など、任意のイテラブルに対しても機能します:
a, *b = (-10, 5, 2, 100)
print(a) # -10
print(b) # [5, 2, 100]
a, *b = 'python'
print(a) # 'p'
print(b) # ['y', 't', 'h', 'o', 'n']
重要なポイントは、`*b`は常にリストになるということです。元のイテラブルがどのような型であっても、`b`はリストとして生成されます。
より複雑な例
拡張アンパッキングでは、さらに複雑な割り当ても可能です。たとえば、最初、2番目、最後の要素をそれぞれ変数に割り当て、残りの要素をまとめて扱うこともできます:
a, b, *c, d = [1, 2, 3, 4, 5]
print(a) # 1
print(b) # 2
print(c) # [3, 4]
print(d) # 5
ここでは、`a`と`b`が最初と2番目の値を受け取り、`d`が最後の値を取り、残りの値が`c`にリストとして格納されます。
さらに、ネストされたアンパッキングも可能です:
a, *b, (c, *d) = [1, 2, 3, 'python']
print(a) # 1
print(b) # [2, 3]
print(c) # 'p'
print(d) # ['y', 't', 'h', 'o', 'n']
イテラブルの結合
拡張アンパッキングは、左辺でのアンパックに限定されません。複数のイテラブルを結合するためにも使用できます。例えば:
l1 = [1, 2, 3]
l2 = [4, 5, 6]
combined = [*l1, *l2]
print(combined) # [1, 2, 3, 4, 5, 6]
これは、リストやタプル、その他のイテラブルを簡潔に結合する方法です。
関数パラメータでの `*args` の力
Pythonの`*args`は、関数で変数の数を柔軟に扱うための強力な方法です。これを使うと、関数に複数の引数を渡し、それらの引数が関数内でタプルに格納されます。
`*args` の基本的な使い方
次に、位置引数を出力する簡単な関数を見てみましょう:
def func1(a, b, *args):
print(a)
print(b)
print(args)
func1(1, 2, 'a', 'b')
出力:
1
2
('a', 'b')
このように、`*args`は追加の引数をタプルにまとめます。最初の2つの引数は`a`と`b`に割り当てられ、残りは`args`に格納されます。
実用例:平均値の計算
次に、任意の数の引数を受け取り、それらの平均値を計算する関数を実装してみましょう:
def avg(*args):
count = len(args)
total = sum(args)
return total / count if count > 0 else 0
print(avg(2, 2, 4, 4)) # 3.0
print(avg()) # 0
この関数は、可変個数の入力を処理し、引数が指定されていない場合はデフォルト値を返します。
最低1つの引数を強制する方法
時には、関数に少なくとも1つの引数を必ず渡す必要がある場合もあります。これは、`*args`の前に1つの位置引数を必須にすることで実現できます:
def avg(a, *args):
count = len(args) + 1
total = a + sum(args)
return total / count
print(avg(2, 4, 6)) # 4.0
この場合、最初の引数は必須であり、`*args`は追加の引数を受け取ります。
関数への引数のアンパック
Pythonの強力な機能の1つに、リストやタプルを関数引数としてアンパックできることがあります。これは、既に持っている値のリストを個別の引数として関数に渡したい場合に便利です:
def func1(a, b, c):
print(a)
print(b)
print(c)
l = [10, 20, 30]
func1(*l)
これにより、リストが個別の引数としてアンパックされ、各要素が`a`、`b`、`c`に渡されます。
結論
Pythonの拡張アンパッキングと`*args`は、複雑なデータ構造や関数パラメータを柔軟に扱うための強力な方法です。リストの分解やイテラブルの結合、関数引数の柔軟な処理など、これらの機能を使うことで、より動的で効率的なコードを記述できます。これらのテクニックを習得することで、Pythonでのプログラミングが一層楽しく、効率的になります。
今後もPython 3: Deep Diveシリーズのインサイトをお楽しみに!
この記事が気に入ったらサポートをしてみませんか?