LoginSignup
1
2

More than 3 years have passed since last update.

pythonの*(アスタリスク)引数について(とitertools.starmap)

Posted at

これは何?

mapについてpythonの公式ドキュメント1見ていたとき

map() と starmap() の違いは function(a,b) と function(*c) の差に似ています。

という記述があり、何だコレってなったのがきっかけ。

function(a,b) と function(*c) の差

を知るのが目的

アスタリスク引数の効果

Qiita記事2にすごくよくまとまっていた。
function(a,b) と function(*c) の差と言っているのが、以下のうちどちらかわからない。

def sum1(a,b):
    return a+b

def sum2(*c):
    ret = 0
    for n in c:
        ret += n
    return ret

a = 1
b = 2
c = [a,b]


sum1(a,b)
# > 3

# pattern1
sum1(*c)
# > 3

# pattern2
sum2(*c)
# > 3

pattern1はアンパックであり、
sum1(*c) = sum1(c[0], c[1]) で、len(c) = 2 だから(sum1の引数の数と一致するから)うまく動く。

pattern2は可変長の引数に対する処理で、
len(c)がいくつであってもうまく動く。

関数の*引数についてはよくわかったが、せっかくなので、starmap()について見てみる。

itertools.startmap()

公式ドキュメント1にあるように

list(starmap(pow, [[2,3],[3,4],[4,5]]))
# --> 32 9 1000

となる。
これは$2^{3}, 3^{4}, 4^{5}$のように
第2引数、$[a,b,c,\cdots]$に対して
$a[0]^{a[1]},b[0]^{b[1]},c[0]^{c[1]}, \cdots$を計算していることがわかる。
同じように

list(starmap(sum, [[2,3],[3,4],[4,5]]))

とすれば、$2+3, 3+4, 4+5$を計算してくれるだろうと思っていたが

TypeError: 'int' object is not iterable

と出てくる。
int object…?

list(starmap(sum, [[2,3,4],[3,4,5],[4,5,6]]))

とすると

TypeError: sum() takes at most 2 arguments (3 given)

だと…。
なるほど、3 givenということは、2, 3, 4の3つを引数だと思ったのか。
sum([2,3,4])ではなく、sum(2,3,4)として扱われたということか。

[2,3]のときも
sum(2,3)として扱われて、第1引数が2でintが入っていたため

TypeError: 'int' object is not iterable

このErrorが出たのか。
公式ドキュメント3によるとPython3.8以降では

sum(iterable, /, start=0)

らしくて、第2引数で下駄を履かせられるようになったらしい。

話をもとに戻して、$2+3, 3+4, 4+5$とを計算するためには

list(starmap(sum, [[[2,3]],[[3,4]],[[4,5]]]))
# [5, 7, 9]

とすれば良い。
つまりstarmapは

starmap(func, [funcに入れる引数, funcに入れる引数,...])

と理解すれば良さそう

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2