【Python】関数の引数でリストを使う
Pythonにおいて引数にリストを使用する関数について解説します。
リストの任意の要素を変える関数
コード例
# リストの任意の要素の値を更新する
def list_change(lst: list, idx: int, val: int) -> list:
"""lst[idx]の値をvalに更新"""
lst[idx] = val
x = [1, 2, 3, 4, 5]
print(f'x = {x}')
print(f'id(x) = {id(x)}')
index = int(input('インデックス値 : '))
value = int(input('更新後の値 : '))
list_change(x, index, value)
print(f'x = {x}')
print(f'id(x) = {id(x)}')
実行結果
x = [1, 2, 3, 4, 5]
id(x) = 1990268245696
インデックス値 : 2
更新後の値 : 9
x = [1, 2, 9, 4, 5]
id(x) = 1990268245696
この関数ではリストlst内のインデックス値idx、すなわちlst[idx]の値をvalに更新しています。
今回はx[2]が3から9に変わっているのがわかります。
こうなるのは引数となるリストがミュータブルだからです。
引数がミュータブルであれば関数内で仮引数を変更するとそのオブジェクト自体が更新され呼び出し側の実引数も更新されます。
上のコードで関数による更新前後のリストの識別番号がどちらも同じであることからもわかります。
イテラブル型実引数のアンパック
上のコードでは仮引数も実引数もリストでした。
では実引数はリストなのに対し仮引数が(a, b, c)と違う場合はそのままでは無理です。
それぞれa, b, cにリストの各要素を代入、つまりアンパックしなくてはいけません。
コード例
# リストのアンパック
lst = [1, 2, 3]
a, b, c = lst
ただこのようなことを毎回するのは面倒くさいです。
実引数の前に*を付けるだけで自動的にアンパックされて関数に渡されます。
コード例
# リストの3値の最小値を求める
def list_min3(a, b, c):
"""aとbとcの最小値を求めて返却"""
min = a
if b < min: min = b
if c < min: min = c
return min
lst = [1, 2, 3]
mini = list_min3(*lst)
print(f'{lst}の最小値は{mini}です。')
実行結果
[1, 2, 3]の最小値は1です。
リストlstの要素がアンパックされて仮引数a,b,cに渡されています。
その結果として最小値1が正しく求まります。
仮引数 | 値 |
---|---|
a | 1 |
b | 2 |
c | 3 |
今回はリストの要素が仮引数と同じ3でしたがこれが2や4などのように異なるとエラーが発生します。
仮引数にデフォルト値を設定すれば実引数側の要素が少なくても正しく動きます。
コード例
def list_min3(a, b, c=0):
上のように設定すれば実引数の要素が少ないときにデフォルト値が使われます。
例えば下のようなリストの場合を考えます。
コード例
lst = [1, 2]
これで関数list_min3に渡すと1と2とデフォルト値の0の3値の最小値0が求まります。
仮引数 | 値 |
---|---|
a | 1 |
b | 2 |
c | 0 |
リストの要素を可変個引数に受け取る
次はリストの要素を足し算する過程と結果を出力する関数を考えます。
コード例
# リストの全要素を加算する過程を表示
def list_sum(a, *no):
"""引数の和と式を表示"""
sum = a
print(a, end='')
n = len(no)
if n > 0:
print(' + ', end='')
for i in range(n - 1):
sum += no[i]
print(no[i], '+ ', end='')
sum += no[n - 1]
print(no[n - 1], end='')
print(' =', sum)
return sum
lst = [1, 2, 3, 4, 5]
list_sum(*lst)
実行結果
1 + 2 + 3 + 4 + 5 = 15
このコードの場合lstの最初の要素1がaに渡され、残りの要素[2, 3, 4, 5]が可変個引数である*noに渡されます。
仮引数 | 値 |
---|---|
a | 1 |
*no | [2, 3, 4, 5] |