プログラミング
記事内に商品プロモーションを含む場合があります

Pythonの可変長引数*argsと*kwargsの使い方と違いを分かりやすく解説

Aru

この記事では、Pythonの関数で可変長引数を受け取る方法について解説します。Pythonには可変長引数を受け取る方法として*args**kwargsがありますが両者には使い方に違いがあります。可変長引数はたまにしか使わないので構文を忘れがちです。この記事では、*args**kwargsの利用方法を再確認できるようにしました。

可変長引数の種類とルール

以下、可変長引数の使い方のメモになります。まずは、以下のルールを理解しましょう。

可変長引数の種類

可変長位置引数(*args)と可変長キーワード引数(**kwarg)が存在

*args**kwargsの違い

*argsは任意の数の引数をタプルとして受け取る
**kwargsは、任意の数のキーワード引数を辞書として受け取る

*args**kwargsを両方同時に利用する場合の制約

両方同時使うことができるが、*args**kwargsになければならない
つまり、*args→**kwargsの順番である必要がある

特に注意するのは、両方を同時に利用する場合の順番です。*args→**kwargsでなければならないことに気をつけましょう。

可変長位置引数(*args)

*argsの基本的な使い方

可変長位置引数(*argsを使うと任意の数の引数をタプルとして関数に渡すことが可能です。例のように、整数、文字列、リストなどさまざまな型を受け取ることができます。

def f(*args):
    print(args)
    for e in args:
        print(e)

f(10, 20, "abc", [1, 2, 3])
# (10, 20, 'abc', [1, 2, 3])
# 10
# 20
# abc
# [1, 2, 3]

なお、引数名は*argsでなくてもOKです。例えば、*elementに変更しても同様の結果になります(個人的には、分かりやすいように*argsをお勧めします)

def f(*elements):
    print(elements)
    for e in elements:
        print(e)


f(10, 20, "abc", [1, 2, 3])
# (10, 20, 'abc', [1, 2, 3])
# 10
# 20
# abc
# [1, 2, 3]

*argsの応用例

例えば、任意個の数値を受け取って、平均値と最大値、最小値を取る関数などを作成することができます。

不特定数の引数(個数が決まっていない引数)を受け取って処理したい場合に便利です。

以下は、不特定数の値を受け取って、平均と最大値、最小値を返す例です。

def calc(*args) :
    total = 0
    nmin, nmax = args[0], args[0]
    for i in args :
        total += i
        nmin = min(nmin, i)
        nmax = max(nmax, i)
    return total/len(args), nmin, nmax

print(calc(10,3,40,2))
# (13.75, 2, 40)

可変長キーワード引数(**kwargs)

**kwargsの基本的な使い方

可変長キーワード引数(**kwargsは、任意の数のキーワード引数を辞書として関数に渡すことができるものです。アスタリスクが2つ付いていれば、変数名はkwargsでなくて構いません(こちらも、個人的には**kwargsという名前にしておくことをお勧めします)。

以下は、**kwargsの例です。

def f(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

f(name="taro", age=30, sex="male")
# name: taro
# age: 30
# sex: male

*kwargsの応用例

可変長キーワード引数は、オプションなどを受け取る場合に便利です。

下記の例では、キーワードが存在する場合は、パラメータに代入し、存在しない場合は規定値を代入しています。

もう少し詳しくプログラムを解説すると、if xxx in kwargsxxxが引数に含まれているか確認し、含まれていた場合には引数で指定された値をパラメータに代入しています。

def f(**kwargs):
    name, age, sex = None, None, None
    if "name" in kwargs:
        name =  kwargs["name"]
    else :
        name = "no name"
    if "age" in kwargs:
        age = kwargs["age"]
    else :
        age = "no age"
    if "sex" in kwargs:
        sex = kwargs["sex"]
    else :
        sex = "no sex"

    print(name, age, sex)

f(name="taro", age=30, sex="male")
# taro 30 male

以上のように、可変長キーワード引数は、不特定数のパラメータを受け取る場合に便利です。

自身が処理できるパラメータだけ処理し、あとは他の関数に任せるパターン

関数がさらにパラメータを持った関数を呼び出す場合、以下のようなコードで実現することができます。

下記の例は、関数fはパラメータnameだけを処理し、関数fから呼び出された関数gagesexを利用する例です。

可変長キーワード引数を使うと、それぞれの関数が受け取るパラメータを呼び出し側で一括して指定することができます。

def f(**kwargs):
    print(kwargs["name"])
    g(kwargs)

def g(kwargs):
    print(kwargs["age"], kwargs["sex"])

f(name="taro", age=30, sex="male")
# taro
# 30 male

各関数が処理できるものだけを受け取り、他のパラメータは他の関数へ渡す形です。このような実装を行なっているライブラリが結構ある印象です。

*argと**kwargsを組み合わせる

*arg**kwargsを組み合わせる場合、*argsを手前に記述する必要があります。

argsが手前です。間違えないように!

def f(*args, **kwargs):
    op = "add"
    if "op" in kwargs :
        op = kwargs["op"]

    tot = 0 if op == "add" else 1
    for i in args :
        if op == "add" :
            tot += i
        elif op == "mul" :
            tot *= i
    
    return tot

print(f(1,2,3,4, op="add"))
# 10
print(f(1,2,3,4, op="mul"))
# 24

まとめ

Pythonで可変長引数を利用する方法を説明しました。特に**kwargsは色々なライブラリでも使われているので可変長引数について理解していると、ライブラリの理解の助けになるかと思います。

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

ABOUT ME
ある/Aru
ある/Aru
IT&機械学習エンジニア/ファイナンシャルプランナー(CFP®)
専門分野は並列処理・画像処理・機械学習・ディープラーニング。プログラミング言語はC, C++, Go, Pythonを中心として色々利用。現在は、Kaggle, 競プロなどをしながら悠々自適に活動中
記事URLをコピーしました