カテゴリー

当サイトはアフィリエイトプログラムによる収益を得ています〈景品表示法に基づく表記です)

Python基礎

【python&関数化】defとかargsとかを使って関数を作成する

2021年7月27日

こんな人にオススメ

pythonのdefってあるけど、あれって何?関数にするとかなんとからしいけど使い方とかメリットがわからん!

ということで、pythonのdefの役割とメリットなどを解説する。既に本ブログでは腐るほどのdefを使用してきたが、改まってこのようにしてdefについて書くのは初めて。

かくいう執筆者自身も今回の疑問のようにそもそもdefって何なのかとかどういうメリットがあるのかといったことがわからずにずっと使ってこなかった。

しかし、一旦使うと結構便利なもので、使い始めてからほとんど全ての研究.pyファイルに活用している。

python環境は以下。

  • Python 3.9.4
  • numpy 1.20.3

運営者のメガネです。YouTubeTwitterInstagram、自己紹介はこちら、お問い合わせはこちらから。

運営者メガネ

defを使うメリット

まずはそもそもdefを使うメリットをお話しする。defを使わなくてもコードは書けるし実際にプログラムは動く。じゃあなんでわざわざ小難しいdefを使わないといけないのか。

それは楽ができるから(と思っている)。

defで関数を定義

import numpy as np

# defで関数を定義
# a, b, cはex関数の引数
def cal(a, b, c):
    """3つの引数より複雑な計算を行う
    defでの関数定義の練習計算

    Parameters
    ----------
    a : int or float
        引数1
    b : int or float
        引数2
    c : int or float
        引数3

    Returns
    -------
    float
        計算結果
    """

    # 以下cal1, cal2, cal3, ansは処理
    cal1 = a ** 2 + b ** 2
    cal2 = np.sqrt(cal1)
    cal3 = cal2 + 1

    ans = cal3 * c

    # returnで値を返すことができる
    return ans

そもそもdefは上のコードのような感じで、def (関数名)((引数)):という構成で記述する。で、インデントをつけた後にいつも通りコードを書く。

その下についている"""で書かれた部分はdocstringといって、書いた関数がどのような内容でどんな引数や返り値(戻り値)を返すのかなどを記述する。

なお、執筆者はVScodeの「Python Docstring Generator」で自動生成している。VScodeの拡張機能については以下参照。

[card2 id="ID"]

defを使うメリット

lst1 = []
for i in range(3):
    a = i
    b = i ** 2
    c = i + 2

    # 予め定義しておくとコードが短縮できる
    # calは戻り値(返り値)があるので代入して値を使用できる
    ans = cal(a=a, b=b, c=c)
    lst1.append(ans)
print(lst1)
# [2.0, 7.242640687119285, 21.88854381999832]

ではdefを使うことのメリットについてだが、例えば先程のcal関数では複雑な処理を行なっている。しかし、一度関数を定義しておくと上のコードのようにコードを短縮して書くことができる。

また、cal関数に書かれた内容を再度使用する時にも、予め関数化しておくとその関数を呼び出すだけで使用できるので楽。

a = 10
b = 3
c = 1
# 再度使用する時にコードが短くて済む
ans = cal(a=a, b=b, c=c)
ans2 = cal(a=a, b=b, c=c) * 2
print(ans)
# 11.44030650891055
print(ans2)
# 22.8806130178211

返り値(戻り値)がない場合

def no_return(a, b, c):
    """3つの引数を出力

    Parameters
    ----------
    a : list
        引数1
    b : int
        引数2
    c : str
        引数3
    """

    # 返り値はなくてもいい
    # 返り値がない場合に関数の結果を代入するとNoneになる
    print(f"a: {a}, b: {b}, c: {c}")

先程のcal関数だとreturnとして返り値(戻り値)が設定されていたが、returnがない場合(返り値がない)もある。上の例だとreturnの代わりにprintが存在している。

この場合にこの関数を使用すると関数内にprintがあるので、関数を使用するだけでprint文が出力される。

# 代入するだけでも関数を使用するのでprintされる
ans = no_return(a=[1, 2, 3], b=1, c='str')
# a: [1, 2, 3], b: 1, c: str

で、このno_return関数を変数に代入すると何が代入されるのかというとNoneが返される。

# 単発で使ってもprintされる
no_return(a=[1, 2, 3], b=1, c='str')
# a: [1, 2, 3], b: 1, c: str

返り値がない場合に変数を代入してもエラーが出ることははないが、それでも誤解を与えかねない気がするので明確に戻り値があるかどうかは分けたほうがいいだろう。

引数指定時の=と引数の順番

上で色々と関数を作成して挙動を調べていたが、ここでは引数を入れる時の挙動について解説する。

=はあってもなくてもいい

# defで関数を定義
# a, b, cはex関数の匹数
def add(a, b, c):
    """3つの引数より簡単な計算を行う

    Parameters
    ----------
    a : int or float
        引数1
    b : int or float
        引数2
    c : int or float
        引数3

    Returns
    -------
    float
        計算結果
    """

    ans = a + (- b) + c
    return ans

add関数はシンプルに引数を足していく関数。全ての引数を指定して値を入れるともちろん正しく計算されるので大丈夫。

# 全ての引数に=をつけるとその引数に代入される
ans = add(a=1, b=2, c=3)
print(ans)
# 2

また、引数を指定している場合は関数を定義したときの順番で書かなくても正しく計算される。どの引数にどの値を入れるのかが指定されているから。

# 引数の順番を変えることも可能
ans = add(b=2, a=1, c=3)
print(ans)
# 2

=をつけなくても正しく動くけど、その時は関数を定義した順番で引数に代入されていく。add関数でいうとa, b, cの順番に強制的に値が代入されていく。

# =をつけなくてもいいが、その時は定義時の引数の順番で代入される
ans = add(1, 2, 3)
print(ans)
# 2

代入する値がlisttupleでまとまっているならアンパック(展開)して代入することも可能。アンパックは*を使って行う。

# 引数指定はアンパック(展開)でも可能
lst = [1, 2, 3]
ans = add(*lst)
print(ans)
# 2

=の省略と引数指定

# =の前なら引数の指定はなしでもいい
ans = add(1, b=2, c=3)
print(ans)
# 2

さっきは全ての引数に対して=をつけるか全てにつけないかの0, 100理論だった。上の例では初めの匹数aだけは引数指定なしでその他の引数指定をしている。この場合でも正しく計算される。

また、先程同様、引数指定をしていると順番を入れ替えても大丈夫。

# 引数名入りなら順番を変更してもいい
ans = add(1, c=3, b=2)
print(ans)
# 2

しかし、引数指定をした後で引数指定をしない引数を入れるのはエラー。値をどの引数に入れたらいいのかがわからなくなるから。今回はaだけ指定したが、この場合はbcにそれぞれ23のどちらを入れたらいいのかがわからない。

# 引数指定したあとは引数指定なしは不可
ans = add(a=1, 2, 3)
#     ans = add(a=1, 2, 3)
#                        ^
# SyntaxError: positional argument follows keyword argument

引数の数は合わせないといけない

# 引数が足りない
ans = add(1, 2)
#     ans = add(1, 2)
# TypeError: add() missing 1 required positional argument: 'c'

add関数にはa, b, cの合計3つの引数が存在している。なので、引数が足りないとエラーになる。これは引数が多い場合も同様。

# 引数が多い
ans = add(1, 2, 3, 4)
#     ans = add(1, 2, 3, 4)
# TypeError: add() takes 3 positional arguments but 4 were given

また、勝手に引数を作成するのもエラー。dなんて引数はないということだ。

# 引数を勝手に作ってはいけない
ans = add(a=1, b=2, c=3, d=10)
#     ans = add(a=1, b=2, c=3, d=10)
# TypeError: add() got an unexpected keyword argument 'd'

引数のデフォルトの値を設定

関数っていうのは同じ処理・コードを繰り返し使うときに、処理を予め定義しておくと楽というメリットがあることは上に書いた通り。しかし、引数も予め決まった値が入ることが高い場合はどうだろう。

具体的には、ある引数は基本10だけどあるタイミングでは1にしたい時があるとか。defでは引数のデフォルト値を設定することができるのでこの問題は解決する。

デフォルト値があると引数は省略可能

# default関数は引数cのデフォルト値が10
def default(a, b, c=10):
    """3つの引数を出力

    Parameters
    ----------
    a : int
        引数1
    b : int
        引数2
    c : int, optional
        引数3, by default 10
    """
    print(f"a: {a}, b: {b}, c: {c}")

default関数は引数としてa, b, cを持つ関数だが、引数のうちcに関してはデフォルト値として10が指定されている。docstringにもこの旨を記載する必要がある。

cの値がデフォルトで入っているのでわざわざ指定しなくても大丈夫。もちろんこの時のcの値は10

# cはデフォルト値があるので省略可能
default(a=1, b=2)
# a: 1, b: 2, c: 10

cの値はあくまでもデフォルト値なので上書きすることも可能。以下の例ではcの値を1に上書きした。上書きなのでcデフォルト値の10ではなく新規の1で計算される。

# cを上書き
default(a=1, b=2, c=1)
# a: 1, b: 2, c: 1

もちろんデフォルト値ではない引数を省略することはできない。default関数はcだけデフォルト値が設定されているのでbは省略できない。だって値がわからなくなるもん。

# デフォルト値がない引数は省略できない
default(a=1)
#     default(a=1)
# TypeError: default() missing 1 required positional argument: 'b'

引数をboolにすると便利

# 引数にboolを持ってくるとしたい処理に対して便利に対応できる
def default_tf(check=False):
    """checkの真偽で出力内容を変更する

    Parameters
    ----------
    check : bool, optional
        チェックを入れるか否か, by default False
    """

    if check:  # check = Trueの時
        print('check入りまーす')
    else:
        print('何もないよ')

個人的に便利な使いかたとして挙げているデフォルト値の使い方がboolを入れるというもの。boolというのはTrueFalseのことで、ifで条件分岐する際にコードを短く書くことができる。

# 引数指定を改行しておけばすぐに切り替えられる
default_tf(
    check=True
)
# check入りまーす

# デフォルトがFalseなので、引数を指定しないとFalse時の出力となる
default_tf(
    # check=True
)
# 何もないよ

じゃあどんな時に使えそうかということだが、執筆者自身はplotlyでグラフを作った時にそのグラフを表示するかどうか、保存するかどうかの判定に使っている。

基本的にはグラフを表示しながらちゃんと目的通りのグラフができているかをグラフ表示の引数をTreuで確認しつつ、保存する時には保存するとして保存の引数をTrueにする。

大量にグラフを保存したい時は表示をFalseにして保存をTrueにすればいちいち表示しなくても勝手に保存されていく。デフォルト値があるとTrueからFalseに書き換えなくてもコメントアウトだけで事足りるから便利。

可変長引数*argsで任意の数の引数を使用

これまでは引数の数が3つとかで規定の数だった。しかし、数が不明瞭な場合があるかもしれない。ある状況では引数が3個だが、別の状況だと10個になるとか。

listとかにまとめて引数として入れて処理することも可能だが、ここでは可変長引数*argsというものを使用して、任意の数の引数を直接、関数に入力する方法を解説する。

ちなみにargs = argumentsの略で「可変長tuple」というらしい。tupleと名づいているのは、受け取った任意の数の引数がtupleに入れられるから。

可変長引数*argsで任意の数の引数を指定

# 可変長引数は慣例的にargsを使用する
def args_def(*args):

    print(f"args: {args}")
    print(f"type(args): {type(args)}")

可変長引数を使用するには*を使用する。実は「args」という文字にこだわる必要はなく、*nameでも*hikisuでも大丈夫。しかし慣例的に*argsになっているのでここでもそれに倣う。

上のargs_def関数では入力されたargsとその型を出力する関数。実際に1, 2, 3を入れてみる。入力時には直接、値を入れるだけでいい。便利。

# 好きな数の引数を入れられる
args_def(1, 2, 3)
# args: (1, 2, 3)
# type(args): <class 'tuple'>

args_def(10, 20, 3, 'moji')
# args: (10, 20, 3, 'moji')
# type(args): <class 'tuple'>

argsに入れられた引数達はtupleにまとめられていることがわかる。tupleにまとめられるのでforループで1要素ずつ取り出すことが可能。

# 可変長引数はtupleで入るので、そのままforに使える
def args_def_for(*args):

    for num, arg in enumerate(args):
        print(f"args[{num}]: {arg}")

args_def_for('1', [1, 2, 3], True, None)
# args[0]: 1
# args[1]: [1, 2, 3]
# args[2]: True
# args[3]: None

*argsと通常の引数を併用

def args_def_other(*args, a, b, c=10):

    print(f"args: {args}")
    print(f"a: {a}")
    print(f"b: {b}")
    print(f"c: {c}")

    print(f"type(args): {type(args)}")
    print(f"type(a): {type(a)}")
    print(f"type(b): {type(b)}")
    print(f"type(c): {type(c)}")

可変長引数という特殊な引数を紹介したが、通常の引数と一緒に使えないのかというとそうではない。使える。以下の例だと、1, 2, 3argsに、その他の引数は指定の引数に入れられる。

# 可変長ではない引数との併用も可能
args_def_other(1, 2, 3, a=10, b=20, c=30)
# args: (1, 2, 3)
# a: 10
# b: 20
# c: 30
# type(args): <class 'tuple'>
# type(a): <class 'int'>
# type(b): <class 'int'>
# type(c): <class 'int'>

もちろんデフォルト値との併用も可能でargs_def_other関数ではcがデフォルトで値が決められているのでcの指定を省略できる。

# デフォルト値のある引数との併用も可能
args_def_other(1, 2, 3, a=10, b=20)
# args: (1, 2, 3)
# a: 10
# b: 20
# c: 10
# type(args): <class 'tuple'>
# type(a): <class 'int'>
# type(b): <class 'int'>
# type(c): <class 'int'>

ただし、引数の自動的な数合わせをしてくれるわけではない。どこからどこまでがargsでどこからどこまでがa, b, cなのかを指定する必要がある。

たとえデフォルト値のあるcを指定してもエラーが出る。しっかりと指定しましょう。

# 省略したら勝手に数合わせをしてくれるわけではない
args_def_other(1, 2, 3, 10)
#     args_def_other(1, 2, 3, 10)
# TypeError: args_def_other() missing 2 required keyword-only arguments: 'a' and 'b'

# cを入れても勝手に数合わせをしてくれないよう
args_def_other(1, 2, 3, c=30)
#     args_def_other(1, 2, 3, c=30)
# TypeError: args_def_other() missing 2 required keyword-only arguments: 'a' and 'b'

*argsを最後に持ってくる

def args_def_end(a, b, *args):

    print(f"a: {a}")
    print(f"b: {b}")
    print(f"args: {args}")

    print(f"type(a): {type(a)}")
    print(f"type(b): {type(b)}")
    print(f"type(args): {type(args)}")

先ほどまでは*argsを最初に持ってきたが、ここでは*argsを最後に持ってくる。まずは先程最後の引数指定のことを踏まえてa, bを引数名指定して、argsを直接書いてみた。エラー。

a, bで引数指定をしてしまったから、その後の値はどの引数かわからんよ状態。

# a, bを引数指定するとエラー
args_def_end(a=1, b=2, 10, 20, 30)
#     args_def_end(a=1, b=2, 10, 20, 30)
#                                        ^
# SyntaxError: positional argument follows keyword argument

なるほど、ならargs=と書けばいいじゃない。エラー。そんなんねーよと。

# argsを引数指定しようとすると引数名にそんなん無いと
args_def_end(a=1, b=2, args=(10, 20, 30))
#     args_def_end(a=1, b=2, args=(10, 20, 30))
# TypeError: args_def_end() got an unexpected keyword argument 'args'

ならばargsを展開してみる。エラー。そもそもの文法ミス判定。

# 展開して入れようとしてもエラー
args_def_end(a=1, b=2, *args=(10, 20, 30))
#     args_def_end(a=1, b=2, *args=(10, 20, 30))
#                                   ^
# SyntaxError: invalid syntax

じゃあどうすればいいかというと、シンプルに全ての引数から引数指定を無くせばいい。でもこれはこれでわかりにくい。どこからどこまでがargsなのかを目で追う必要がありそう。

# 引数指定をしないとOK
args_def_end(1, 2, 10, 20, 30)
# a: 1
# b: 2
# args: (10, 20, 30)
# type(a): <class 'int'>
# type(b): <class 'int'>
# type(args): <class 'tuple'>

*argsを真ん中に持ってくる

def args_def_mid(a, *args, b):

    print(f"a: {a}")
    print(f"args: {args}")
    print(f"b: {b}")

    print(f"type(a): {type(a)}")
    print(f"type(args): {type(args)}")
    print(f"type(b): {type(b)}")

では*argsを真ん中に持ってきてみる。この場合では全ての引数を指定せずに入力するとエラー。bが指定されていないとな。

# bは引数指定が必要
args_def_mid(1, 2, 3, 4)
#     args_def_mid(1, 2, 3, 4)
# TypeError: args_def_mid() missing 1 required keyword-only argument: 'b'

この場合はbを指定する必要がありそう。ややこしい。

# 引数指定をするとOK
args_def_mid(1, 2, 3, b=4)
# a: 1
# b: 4
# args: (2, 3)
# type(a): <class 'int'>
# type(b): <class 'int'>
# type(args): <class 'tuple'>

可変長引数**kwargsで任意の数の引数をdictで使用

先ほどは任意の数の引数を直接使用できるという可変長引数*argsの話だった。ここでは*argsと対を成す**kwargsを解説する。*が増えると意味が全然違ってくる。

*argsでは1’str’といった単発の引数だったが、**kwargsだとa=1b=2といったセットでの引数を使用可能になる。要するにdictっぽいってこと。

ちなみにkwargs = keyword argumentsの略で「キーワード辞書」というらしい。まさしくdict

可変長引数**kwargsで任意の数の引数をdictで指定

# **とすると辞書型を受け付けるようになる
def kwargs_def(**kwargs):

    print(f"kwargs: {kwargs}")
    print(f"type(kwargs): {type(kwargs)}")

**kwargsとすると辞書型を受け付けるので、引数も辞書型が採用される。以下の例ではa, b, cというkey1, 2, 10というvalueを入れてみた。

kwargs_def(a=1, b=2, c=10)
# kwargs: {'a': 1, 'b': 2, 'c': 10}
# type(kwargs): <class 'dict'>

辞書型なので**での展開で引数を入れることも可能。

# dictの展開でも引数の指定が可能
dct = {'a': 1, 'b': 2, 'c': 10}
kwargs_def(**dct)
# kwargs: {'a': 1, 'b': 2, 'c': 10}
# type(kwargs): <class 'dict'>

ただし、引数に数字を持ってくるのはエラー。文字列にした数字をdictの展開で入れるのは大丈夫だが、dictに入れても数字はエラー。

# 数字をkeyに持ってくることはできない
kwargs_def(1=1, b=2, c=10)
#     kwargs_def(1=1, b=2, c=10)
#                ^
# SyntaxError: expression cannot contain assignment, perhaps you meant "=="?

# 予めdictで文字列の数字を使用するとセーフ
dct = {'1': 1, '0.1': 2, 'c': 10}
kwargs_def(**dct)
# kwargs: {'1': 1, '0.1': 2, 'c': 10}
# type(kwargs): <class 'dict'>

# 予めdictでも数字はエラー
dct = {1: 1, '0.1': 2, 'c': 10}
kwargs_def(**dct)
#     kwargs_def(**dct)
# TypeError: keywords must be strings

**kwargsを展開する

def kwargs_def_unpack(**kwargs):
    # f-stringでは{}内で展開出来ない
    # print(f"{*kwargs}")
    # #     (*kwargs)
    # #     ^
    # # SyntaxError: f-string: can't use starred expression here

    # *で引数の展開が可能
    print(*kwargs)

    # print(a=1, b=2, c=10)となるので**での展開はできない
    # print(**kwargs)
    # # TypeError: 'a' is an invalid keyword argument for print()

    # 辞書型なのでvaluesで値を取得可能
    print(*kwargs.values())

    # どちらも欲しい時はitems()
    print(*kwargs.items())

kwargsを展開する方法はいくつかあるが、f-stringで展開することとprint**の展開をするのはエラー。ただし、print*の展開はセーフ。

シンプルに*で展開するとkeyを、.values()で展開するとvalueを、.items()で展開するとkeyvalueを取得可能。

kwargs_def_unpack(a=1, b=2, c=10)
# a b c
# 1 2 10
# ('a', 1) ('b', 2) ('c', 10)

**kwargsを最後に持ってくる

def kwargs_def_end(A, B, **kwargs):

    print(f"A: {A}")
    print(f"B: {B}")
    print(f"kwargs: {kwargs}")

    print(f"type(A): {type(A)}")
    print(f"type(B): {type(B)}")
    print(f"type(kwargs): {type(kwargs)}")

*argsの時と同じように*、**kwargsも最後に持ってきてみる。A, Bを引数指定なしにして**kwargsを引数指定ありにすると正常に動く。

kwargs_def_end(1, 2, a=1, b=0)
# A: 1
# B: 2
# kwargs: {'a': 1, 'b': 0}
# type(A): <class 'int'>
# type(B): <class 'int'>
# type(kwargs): <class 'dict'>

もちろんA, Bの引数指定も可能。

# もちろん通常の引数の=指定も可能
kwargs_def_end(A=10, B=20, a=1, b=0, AA=0.1)
# A: 10
# B: 20
# kwargs: {'a': 1, 'b': 0, 'AA': 0.1}
# type(A): <class 'int'>
# type(B): <class 'int'>
# type(kwargs): <class 'dict'>

しかし、既に引数で指定されているA, B**kwargsで指定するのはエラー。

# 既に引数として存在している引数は可変長で入れることができない
kwargs_def_end(1, 2, A=1, b=0)
#     kwargs_def_end(1, 2, A=1, b=0)
# TypeError: kwargs_def_end() got multiple values for argument 'A'

**kwargsは最後でないといけない

def kwargs_def_mid(A, **kwargs, B=1):

    print(f"A: {A}")
    print(f"kwargs: {kwargs}")
    print(f"B: {B}")

    print(f"type(A): {type(A)}")
    print(f"type(kwargs): {type(kwargs)}")
    print(f"type(B): {type(B)}")

#     def kwargs_def_mid(A, **kwargs, B=1):
#                                     ^
# SyntaxError: invalid syntax

kwargsを真ん中に持ってこようとしたが、なんと真ん中に持ってくるだけでエラー。というのもkwargsは書く際の順番的に最後らしい。

優先順位 引数の種類
1 デフォルト値なしの引数
2 *args
3 デフォルト値ありの引数
4 **kwargs

なので**kwargsはどう足掻いても最後。

*args**kwargsの組み合わせ

def kw_args(*args, **kwargs):
    print(f"args: {args}")
    print(f"kwargs: {kwargs}")

上で*args**kwargsを解説したが、2つの組み合わせも許容される。順番は先ほどに従って*args**kwargsの順番。argsargs=とできないから引数だけ記述、kwargsa=10のように記述。

# 1, 2, 3がargs、a=10, b=20がkwargsに格納
kw_args(1, 2, 3, a=10, b=20)
# args: (1, 2, 3)
# kwargs: {'a': 10, 'b': 20}

argskwargsのどちらか、もしくはどちらも何も入れないと、それぞれ空の配列として出力される。

# kwargsを省略するとkwargsには空のdictが生成
kw_args(1, 2, 3)
# args: (1, 2, 3)
# kwargs: {}

# argsを省略するとargsには空のtupleが生成
kw_args(a=10, b=20)
# args: ()
# kwargs: {'a': 10, 'b': 20}

# args, kwargsどちらも省略するとどちらも空で生成
kw_args()
# args: ()
# kwargs: {}

なお、優先順位よりkwargsを先に持ってくることはできない。

# kwargsを先に書いて後からargsはエラー
kw_args(a=1, 2, 3)
#     kw_args(a=1, 2, 3)
#                      ^
# SyntaxError: positional argument follows keyword argument

複数returnを展開で代入

def multiple_return(a, b, c):

    return a, b, c

最後に今更感はあるが、複数のreturnを展開で変数へ代入する。複数の値をreturnした場合、戻り値はtupleへ格納されて出力される。

# 複数の返り値はtupleに入れられる
ans = multiple_return(a=1, b=2, c=3)
print(ans)
# (1, 2, 3)
print(type(ans))
# <class 'tuple'>

したがって、変数を複数個用意して代入することで展開の容量で返り値を代入することができる。

# 複数個の返り値をその数に合った個数の変数に代入
a, b, c = multiple_return(a=1, b=2, c=3)
print(f"a: {a}, b: {b}, c: {c}")
# a: 1, b: 2, c: 3

代入先の変数が足りていないとエラーとなるが、変数を可変長にするとエラーを回避できる。

# 数が足りていないとエラー
# a, b = multiple_return(a=1, b=2, c=3)
# #     a, b = multiple_return(a=1, b=2, c=3)
# # ValueError: too many values to unpack (expected 2)

# 代入先の変数を可変長にすると残りの返り値を代入可能
a, *b = multiple_return(a=1, b=2, c=3)
print(f"a: {a}, b: {b}")
# a: 1, b: [2, 3]

なお、可変長は最初に持ってきてもいい。この場合は後の引数の数で帳尻が合うように可変長の変数に代入される。

# 可変長は最後に持ってきてもいい
*a, b = multiple_return(a=1, b=2, c=3)
print(f"a: {a}, b: {b}")
# a: [1, 2], b: 3

defで関数化して楽に

今回はpythonのdefを使用して関数化を行った。関数化することで繰り返し同じコードを書く際に、コードを短縮することができる。さらに入力引数が増えた時も可変長引数を使用することで簡単に対応することができる。

また、別ファイルに関数をまとめて入れておくことで、色んなファイルで関数を一元管理できる。すなわち、あの関数どこだっけがなくなる。ただし、1つ編集したらその関数を使用しているファイルでも同様の編集をする危険性はあるが。

(関数を使って、)お前も楽にならないか?

関連記事

plt.rcParamsでデフォルトを変更した後のグラフ
【pltテンプレート】matplotlib.pyplotのグラフ作成テンプレート

続きを見る

テンプレート適用後のplotlyでのグラフ
【plotlyテンプレート】plotlyのグラフ作成テンプレート

続きを見る

【辞書の結合】dictのマージ

続きを見る

【python&初級】のlistとかforとかifとかまとめ

続きを見る

ガジェット

2023/9/18

【デスクツアー2022下半期】モノは少なく、でも効率的に Desk Updating #0

今回はガジェットブロガーなのにデスク環境を構築していない執筆者の ...

ライフハック

2023/9/16

【Audible vs YouTube Premium】耳で聴く音声学習コンテンツを比較

ワイヤレスイヤホンが普及し耳で学習することへのハードルが格段に下 ...

完全ワイヤレスイヤホン(TWS)

2023/9/18

【SENNHEISER MOMENTUM True Wireless 3レビュー】全てが整ったイヤホン

今回は高音質・高機能なSENNHEISERのフラグシップ完全ワイヤレスイヤホン「SENNH ...

ライフハック

2023/3/11

【YouTube Premiumとは】メリットしかないから全員入れ

今回はYouTube Premiumを実際に使ってみてどうなのか、どんなメリット/デメリット ...

マウス

2023/8/17

【Logicool MX ERGOレビュー】疲れない作業効率重視トラックボールマウス

こんな人におすすめ トラックボールマウスの王道Logicool MX ERGOが気になるけどऩ ...

ベストバイ

2023/9/18

【ベストバイ2022】今年買って良かったモノのトップ10

2022年ベストバイ この1年を振り返って執筆者は何を買ったのか。ガジェッ& ...

スマホ

2023/1/15

【楽天モバイル×povo2.0の併用】月1,000円の保険付きデュアルSIM運用

こんな人におすすめ 楽天モバイルとpovo2.0のデュアルSIM運用って実際のとこ ...

マウス

2023/9/16

【Logicool MX ERGO vs MX Master 3】ERGOをメインにした決定的な理由

こんな疑問・お悩みを持っている人におすすめ 執筆者はLogicoolのハイエンӠ ...

macOSアプリケーション

2022/9/30

【Chrome拡張機能】便利で効率的に作業できるおすすめの拡張機能を18個紹介する

こんな人におすすめ Chromeの拡張機能を入れたいけど、調べても同じような ...

macOSアプリケーション

2023/5/3

【Automator活用術】Macで生産性を上げる作業の自動化術

今回はMacに標準でインストールされているアプリ「Automator」を使ってできる ...

Pythonを学びたいけど独学できる時間なんてない人へのすゝめ

執筆者は大学の研究室・大学院にて独学でPythonを習得した。

でも社会人になったら独学で行うには時間も体力もなくて大変だ。

時間がない社会人だからこそプロの教えを乞うのが効率的。

ここでは色んなタイプに合ったプログラミングスクールの紹介をする。

  • この記事を書いた人

メガネ

Webエンジニア駆け出し。独学のPythonで天文学系の大学院を修了。常時金欠のガジェット好きでM2 Pro MacBook Pro(30万円) x Galaxy S22 Ultra(17万円)使いの狂人。自己紹介と半生→変わって楽しいの繰り返しレビュー依頼など→お問い合わせ運営者情報、TwitterX@m_ten_pa、 YouTube@megatenpa、 Threads@megatenpa

-Python基礎
-,