Python
Python3
逆引き

Python3.xのアスタリスク逆引き


前書き

意外と簡潔にまとめた記事が無かったので書いた。

初心者がさっくり理解できることを目的としている。


関数を呼び出すとき


アスタリスク *


ex_a1.py

my_list = [1, 2, 3]

print(*my_list)


実行結果

1 2 3


アンパックと呼ばれるもので、引数としてリストやタプルなどを分解して渡すことを意味する。

つまり、上記の例の場合print(my_list[0], my_list[1], my_list[2])と同じ。

性質上、可変長位置引数の関数と非常に相性がいい。


アスタリスク **


ex_a2.py

my_dict = {'sep': ' / ', 'end': ' おわり\n'}

print(1, 2, 3, **my_dict)


実行結果

1 / 2 / 3 おわり


同じくアンパックだが、こちらは辞書などをキーワード引数として渡すことが出来る。

つまり上記の例の場合、print(1, 2, 3, sep=' / ', end='おわり\n')と同じ。

単体で使うことはあまりなく、だいたい可変長キーワード引数の関数と併せて使う。


関数を定義するとき


アスタリスク * (仮引数名アリ)


ex_b1.py

def compute_product(*nums):

ret = 1
for num in nums:
ret *= num
return ret

print(compute_product(1, 2, 3))



実行結果

6


可変長位置引数 (あるいは単に可変長引数) を取る関数を定義するときに使う。

与えられた実引数はタプルにまとめられる。

通常の仮引数と組み合わせて使うことも可能である。

しかし、*args以降はキーワード引数として呼び出さなければならない。


ex_b2.py

def useless_func(a, b, *args, c, d):

pass

useless_func(1, 2, 3, 4, 5, 6) # NG
useless_func(1, 2, 3, 4, c=5, d=6) # OK


NGな方のコードを実行してしまうと、次のような例外が発生する。

TypeError: useless_func() missing 2 required keyword-only arguments: 'c' and 'd'


アスタリスク * (仮引数名ナシ)


ex_b3.py

def useless_func(a, b, *, c, d):

pass

useless_func(1, 2, 3, 4, c=5, d=6) # NG
useless_func(1, 2, c=5, d=6) # OK


アスタリスク以降の引数を、キーワード引数として受け取ることを強制できる。

可変長位置引数と異なり、余分な実引数を受け取ってしまうこともない。

NGな方のコードを実行してしまうと、次のような例外が発生する。

TypeError: useless_func() takes 2 positional arguments but 4 positional arguments (and 2 keyword-only arguments) were given


アスタリスク **


ex_b4.py

def useless_func(**kwargs):

print(kwargs)

useless_func(a=1, b=2, c=3)



実行結果

{'a': 1, 'b': 2, 'c': 3}


可変長キーワード引数を取る関数を定義するときに使う。

与えられた実引数は辞書としてまとめられ、キーワード・実引数値がそれぞれkey・valueとされる。

ありとあらゆる引数を受け取る関数を定義するときの定型はこんな感じ。


ex_b5.py

def useless_func(*args, **kwargs):

print(args, kwargs)

useless_func(1, 2, 3, a=1, b=2, c=3)



実行結果

(1, 2, 3) {'a': 1, 'b': 2, 'c': 3}



代入文で用いられるアスタリスク *


ex_c1.py

a, b, *other = [1, 2, 3, 4, 5]

print(a, b, other)


実行結果

1 2 [3, 4, 5]


左辺に複数の要素を置くとき、要素のひとつにアスタリスクを付けることが出来る。

上記の例では、左から順に代入を終えたあと、余った要素がotherに放り込まれる。

次のように書いているのと同じ。


ex_c2.py

my_list = [1, 2, 3, 4, 5]

a = my_list[0]
b = my_list[1]
other = my_list[2:]

print(a, b, other)



リストを定義するときのアスタリスク *


ex_d1.py

list1 = [1, 2, 3]

list2 = [9, 8, 7]

my_list = [*list1, *list2]
print(my_list)



実行結果

[1, 2, 3, 9, 8, 7]


この例に限ってはlist1 + list2でも同じことができるが、覚えておくと便利。

見た目も先のアンパックに似ているので、特に違和感なく受け入れられるだろう(多分)。


辞書を定義するときのアスタリスク **


ex_e1.py

fruit_dict = {'リンゴ': 'apple', 'オレンジ': 'orange'}

vegetable_dict = {'キュウリ': 'cucumber', 'にんじん': 'carrot'}

food_dict = {**fruit_dict, **vegetable_dict}
print(food_dict)



実行結果

{'リンゴ': 'apple', 'オレンジ': 'orange', 'キュウリ': 'cucumber', 'にんじん': 'carrot'}


辞書を合成して新たな辞書を作るときによく用いられる。


式と式の間


アスタリスク *


ex_f1.py

def triple(a):

return 3 * a

ただの掛け算。

気を付ける点があるとすれば、NumPyではアダマール積に用いられていることくらい。

また、イテラブルの反復にも用いられる。特に文字列。


ex_f2.py

print('spam' * 3)   # spamspamspam


リストの反復にも使えるが、トラブルを招きやすいので慣れないうちは避けた方が良いだろう。

定型句だと思ってリスト内包表記を使った方がバグが出にくい。


アスタリスク **


ex_f2.py

def compute_square(base):

return base ** 2

ただのべき乗。Pythonでは^ではなく**を使う。

平方根を求める際、math.sqrtなんて持ち出さずとも n ** .5 で済むことは知っておくと便利。


アスタリスク *=, **=


ex_f3.py

n = 10

n *= 3
print(n) # 30

m = 5
m **= 3
print(m) # 125


累積代入文と呼ばれ、意味としてはn = n * 3及びm = m ** 3と一緒。

他言語でも広く使われる記法である。