リストのかけ算

Python初学者が引っかかる落とし穴に、

seq = [[]] * 5
seq[0].append('A')
print(seq)

としたとき、どのような出力が出るか?というのがある。
一見、

[['A'], [], [], [], []]

となりそうだが、実際には

[['A'], ['A'], ['A'], ['A'], ['A']]

となる。

seq = [[]] * 5

という文はちょっとごちゃごちゃして分かりにくいのでちょっと書き直してみると

item = []
seq = [item] * 5

と同じだ。まず空のリストを一つ作成し、そのリストを要素とする長さ1のリストを作る。そして長さ1のリストを *5 して長さ5のリストを作成し、 seq に 代入する。Pythonスクリプトとして書き直すと:

def list_mul(seq, n):
    ret = []
    for i in range(n):
        ret.extend(seq)
    return ret

seq = list_mul([list()], 5)

とこんな感じになる。

つまり、この式では最終的にたった2つのリスト(要素となっているリストと、seqに代入されるリスト)しか存在しない。シーケンスのかけ算は、要素と同じ値のオブジェクトを作成するのではなく、同じ要素を乗数分持ったリストを作成する演算であることを憶えておこう。