このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

【Python入門】可変長引数

可変長引数

 Pythonの関数では、引数の個数が固定されていなくても、呼び出し時に任意の数の値を渡せる「可変長引数」の機能があります。これにより、同じ関数で異なる個数のデータを柔軟に扱うことが可能になり、コードの再利用性や拡張性が大幅に向上します。
 可変長引数は、位置引数として受け取る場合はアスタリスク(*)を、キーワード引数として受け取る場合はダブルアスタリスク(**)を仮引数に付けて定義します。以下では、その基本概念、使い方、および実践例を具体的なプログラムと表を交えて解説します。

プログラムのダウンロード

 「ダウンロード」から、JupyterLab で実行できるサンプルプログラムがダウンロードできます。ファイルは、ESET Endpoint Securityでウイルスチェックをしておりますが、ダウンロードとプログラムの実行は自己責任でお願いいたします。

1.可変長引数の基本概念

 慣例として*args, **kwargsという名前が使われることが多いが、***が先頭についていれば別の名前でも構いません。

  • *args: 複数の引数をタプルとして受け取る。
  • **kwargs: 複数のキーワード引数を辞書として受け取る。

1.1. 位置引数としての可変長引数 (*args)

 位置引数として可変長引数を受け取る場合、関数定義の仮引数の前にアスタリスクを付けます。これにより、呼び出し時に渡された複数の位置引数がタプルとしてまとめられます。

基本構文

def func(*args):
    # args は渡された位置引数を格納したタプルになる
    print(args)

解説

  • *args と記述することで、関数呼び出し時に与えられた任意の数の引数がすべてタプルにまとめられ、変数 args に代入されます。
  • 例えば、実引数が何もない場合は空のタプル ()、1個の場合は ('apple',)、複数の場合は ('apple', 'banana') のように格納されます。

1.2. キーワード引数としての可変長引数 (**kwargs)

 キーワード引数として可変長引数を受け取る場合は、仮引数の前にダブルアスタリスクを付けます。これにより、呼び出し時に渡された複数のキーワード引数が辞書としてまとめられます。

基本構文

def func(**kwargs):
    # kwargs は渡されたキーワード引数を格納した辞書になる
    print(kwargs)

解説

  • **kwargs と記述することで、関数呼び出し時に指定されたキーワード引数(形式は key=value)が辞書にまとめられ、変数 kwargs に格納されます。
  • 例えば、実引数が指定されない場合は空の辞書 {}color='red' なら {'color': 'red'} という形になります。

2.可変長引数の応用例

2.1. 位置引数のみの例

 以下の例は、渡された任意の数の引数をタプルとして受け取り、その内容を表示するシンプルな関数です。

def list_items(*items):
    print("Items received:", items)

# 呼び出し例
list_items()                        # ① 引数なし → 出力: ()
list_items('apple')                 # ② 1個 → 出力: ('apple',)
list_items('apple', 'banana')       # ③ 2個 → 出力: ('apple', 'banana')
list_items('apple', 'banana', 'cherry')  # ④ 3個 → 出力: ('apple', 'banana', 'cherry')

実行結果

Items received: ()
Items received: ('apple',)
Items received: ('apple', 'banana')
Items received: ('apple', 'banana', 'cherry')

解説

  • 関数 list_items*items により、どんな個数の引数もタプルとして受け取ります。
  • 呼び出し例①~④により、引数の個数に応じたタプルの内容がそのまま表示され、位置引数の仕組みが確認できます。

2.2. キーワード引数のみの例

 次に、キーワード引数として渡された引数を辞書として受け取り、その内容を表示する関数の例です。

def show_options(**options):
    print("Options received:", options)

# 呼び出し例
show_options()  # ① 引数なし → 出力: {}
show_options(color='red')  # ② 1個 → 出力: {'color': 'red'}
show_options(color='red', size='large')  # ③ 2個 → 出力: {'color': 'red', 'size': 'large'}

実行結果

Options received: {}
Options received: {'color': 'red'}
Options received: {'color': 'red', 'size': 'large'}

解説

  • 関数 show_options**options によって、キーワード引数が渡されたときの全ての引数を辞書として受け取ります。
  • 呼び出し例により、引数の有無や個数に応じて、受け取る辞書がどのように形成されるかが確認できます。

2.3. 位置引数とキーワード引数の併用

 位置引数とキーワード引数は同時に使用することが可能です。位置引数は先に、キーワード引数は後に記述する必要があります。

def create_menu(*dishes, **extras):
    print("Dishes:")
    for i, dish in enumerate(dishes, 1):
        print(f"  {i}: {dish}")
    if extras:
        print("Extras:")
        for key, value in extras.items():
            print(f"  {key.capitalize()}: {value}")

# 呼び出し例
create_menu('sushi', 'ramen', drink='green tea', dessert='mochi')

実行結果

Dishes:
  1: sushi
  2: ramen
Extras:
  Drink: green tea
  Dessert: mochi

解説

  • *dishes で位置引数をタプルとして受け取り、enumerate を使って番号付きで各料理を表示します。
  • **extras でキーワード引数を辞書として受け取り、追加オプション(例: drink, dessert)を表示します。
    capitalize()メソッド:単語の先頭の一文字を大文字、他を小文字に変換
  • 出力は、位置引数とキーワード引数それぞれの順序や内容が反映され、関数呼び出しの柔軟性を示します。

2.4. 併用例:位置引数、イテラブルアンパッキング、辞書アンパッキングの組み合わせ

 位置引数やキーワード引数は、さらにイテラブルや辞書をアンパックして渡すこともできます。以下の例は、料理メニューを番号付きで表示する display_menu 関数を定義し、位置引数、イテラブルアンパッキング(*)、辞書アンパッキング(**)を組み合わせて呼び出す例です。

def display_menu(main, side, drink):
    print("Menu:")
    print("  Main  :", main)
    print("  Side  :", side)
    print("  Drink :", drink)

# 位置引数としてのイテラブルアンパッキングの例
menu_items = ['burger', 'fries']
display_menu(*menu_items, drink='cola')
# 呼び出し時、menu_items の要素が main, side に展開され、drink はキーワード引数で指定される

# 辞書アンパッキングの例
menu_details = {'main': 'pasta', 'side': 'garlic bread', 'drink': 'lemonade'}
display_menu(**menu_details)

実行結果

Menu:
  Main  : burger
  Side  : fries
  Drink : cola
Menu:
  Main  : pasta
  Side  : garlic bread
  Drink : lemonade

解説

  • 最初の呼び出しでは、リスト menu_items の2要素がアンパックされて mainside に割り当てられ、drink'cola' として指定されます。
  • 次の呼び出しでは、辞書 menu_details の各キーと値が、キーワード引数として正しく展開され、関数内で一致する仮引数に割り当てられます。

【表:可変長引数の種類と特徴】

引数の種類記述方法特徴
位置引数の可変長引数 (*args)def func(*args):呼び出し時に渡された複数の位置引数をタプルとして受け取る
キーワード引数の可変長引数 (**kwargs)def func(**kwargs):呼び出し時に渡された複数のキーワード引数を辞書として受け取る
両者の併用def func(*args, **kwargs):位置引数はタプル、キーワード引数は辞書として同時に受け取る。位置引数は先に記述

まとめ

 可変長引数を活用することで、関数に渡す引数の個数を柔軟に管理でき、呼び出し時の仕様に応じた多様なデータの受け渡しが可能になります。

  • 位置引数(*args):複数の位置引数をタプルとして受け取り、順番に処理できます。
  • **キーワード引数(kwargs):複数のキーワード引数を辞書として受け取り、キーと値のペアで管理できます。
  • 併用:位置引数とキーワード引数を同時に利用することで、関数の呼び出しをより柔軟かつ強力に行うことが可能です。
  • 応用例:料理メニューの表示やその他の複合的なデータ受け渡しに、アンパッキング機能を効果的に利用できます。

 これらのテクニックを活用して、再利用性の高い柔軟な関数を設計し、保守性のあるプログラム作成に役立てましょう。