魂の生命の領域

AWS とか Python とか本読んだ感想とか哲学とか書きます

組み込み型の join メソッドとか map とか

docs.python.org

とりあえず int 形のリストを用意します。

>>> a = list(range(10))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

これを標準出力にこんな感じで出したいとします。

0 1 2 3 4 5 6 7 8 9

よく思いつくのが str.join() メソッドですよね。

ですが、実行してみるとダメだとわかります。

>>> " ".join(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected str instance, int found

エラーメッセージの言う通り、join の引数は文字列のシーケンスじゃないといけないわけです。

当然ですが item 00 はインデックスの話で仮に0番目だけ str にしても次の要素でダメだったら同じです。

>>> " ".join(["1", 2, 3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 1: expected str instance, int found
>>> " ".join(["1", "2", 3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 2: expected str instance, int found

というわけでこの a を文字列のリストにしたいわけですが

>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

シンプルにはこうですよね。

>>> list(map(str, a))
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

いや、実は恥ずかしながらちょっと前までこうやってました。

>>> list(map(lambda x: str(x), a))
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

map() の第一引数には lambda 式を入れるものだというので思考停止してました。

で、join() の引数にこいつを入れれば良さそうです。

ですが join() の引数はリストであることが必要条件ではなくイテラブルであることなので、これで済みます。

>>> " ".join(map(str, a))
'0 1 2 3 4 5 6 7 8 9'

こんなん書いたらダメだぞ!(冗長)

>>> " ".join(list(map(lambda x: str(x), a)))
'0 1 2 3 4 5 6 7 8 9'

内包表記アンチでもなければこれでもいいと思いますが…

>>> " ".join(str(s) for s in a)
'0 1 2 3 4 5 6 7 8 9'