python3のアスタリスクって何?
 Author: 水卜

JavaScriptのスプレッド演算子とよく似ている。

なくても生きていけるけど、知ってると綺麗に書ける。

アスタリスクは乗算とかべき乗でも使うが、JSのスプレッド演算子っぽく使う方を解説したい。

# 乗算
print(3 * 3)
# 9
print('hello' * 2)
# 'hellohello'

# べき乗
print(2 ** 3)
# 8

# 平方根
print(3 ** .5)
# 1.7320508075688772

リストやタプルの展開

リストやタプルの中身を展開して関数に渡せる。

f = lambda a, b, c: a + b + c
sample_list = ['aa', 'bb', 'cc']
f(*sample_list)
# 'aabbcc'

以下に示す、JavaScriptのスプレッド演算子と同じことができる。

const f = (a, b, c) => {
  return a + b + c
}
const sampleList = ['aa', 'bb', 'cc']
f(...sampleList)
// 'aabbcc'

リストの結合

これもJSのスプレッド演算子と同じことができる

list1 = ['a', 'b', 'c']
list2 = ['d', 'e']
merged = [*list1, *list2]
# ['a', 'b', 'c', 'd', 'e']

オブジェクト展開

オブジェクトに対して*を当てると、キーだけが展開される。

obj = {'name': 'Hoge', 'age': 21}
print(*obj)
# name age
print(*obj.items())
# ('name', 'Hoge') ('age', 21)

アスタリスク2つ**

オブジェクトに対しては基本的にアスタリスク2つをつける。

オブジェクト結合

sample_a = {'a': 1, b: 2}
sample_b = {'c': 3, 'd': 4}

merged = {**sample_a, **sample_b}
# {'a': 1, b: 2, 'c': 3, 'd': 4}

関数呼び出し

以下の例のように、キーワード引数付きで呼び出せる。

f = lambda name, age: f'Name is {name}, {age} years old.'
obj = {'name': 'Hoge', 'age': 21}
f(**obj)
# 'Name is Hoge, 21 years old.'

# 以下のように書くのと同じ
f(name=obj['name'], age=obj['age'])
# 'Name is Hoge, 21 years old.'

可変長引数

引数の前に*をつければ可変長引数を受け取れる

from typing import Callable

# 本題と逸れるが、lambdaの型ヒントはこんな感じで書くのがおすすめ
f: Callable[[int], int] = lambda *args: sum(args)
f(1, 2, 3, 4, 5)
# 15

# 例をlambdaで書いているがdefでも同じ
def f(*args: int):
	return sum(args)
f(1, 2, 3, 4, 5)
# 15

キーワード引数の強制

引数に*を入れると、以降の引数はキーワード付きで呼び出されるのが必須になる。

from typing import Callable

f: Callable[[str, str], str] = lambda *, name, age: f'Name is {name}, {age} years old.'

# キーワードをつけずに呼び出すとエラーになる
f('Hoge', 21)
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: <lambda>() takes 0 positional arguments but 2 were given

# キーワードをつければOK
f(name='Hoge', age=21)
# 'Name is Hoge, 21 years old.'