ここが変だよpython


ここんとこ梅雨明けしてくれないせい(おかげ?)でpython書きばっか。てなことしてたら、pythonのなんか変なとこでハマってしまった。
例えば、Rとかでもよくやるのが、任意サイズの空行列なり空データフレームを作っておいて、後でゴニョゴニョしたデータをそんなかに投げ込むとかゆー処理。Rでやるときは、まこんなかんじで
[cpp]
test <-matrix(data="hogehoge",nrow=3,ncol=3)
test
##結果はこんな感じ
[,1] [,2] [,3]
[1,] "hogehoge" "hogehoge" "hogehoge"
[2,] "hogehoge" "hogehoge" "hogehoge"
[3,] "hogehoge" "hogehoge" "hogehoge"
[/cpp] 
で、データを書き換えるときはこんな感じ。
[cpp]
test[2,2] <- "egg"
test
##結果
[,1] [,2] [,3]
[1,] "hogehoge" "hogehoge" "hogehoge"
[2,] "hogehoge" "egg" "hogehoge"
[3,] "hogehoge" "hogehoge" "hogehoge"
[/cpp]

って、ひっじょーに合点のいく作り方なわけです。ところが、pythonでやろうするとかなりへんてこな作り方しないとあきまてん。

[python]
test = 3*[3*["hogehoge"]]
test
##結果はこんな感じ
[[‘hogehoge’, ‘hogehoge’, ‘hogehoge’], [‘hogehoge’, ‘hogehoge’, ‘hogehoge’], [‘hogehoge’, ‘hogehoge’, ‘hogehoge’]]
[/python]

しかし、このへんてこな行列も実は間違い。なぜなら値を代入してみると・・・
[python]
test[2][2] = ‘egg’
test
[[‘hogehoge’, ‘hogehoge’, ‘egg’], [‘hogehoge’, ‘hogehoge’, ‘egg’], [‘hogehoge’, ‘hogehoge’, ‘egg’]]
[/python]
なんか、訳わからない結果になってしまいます。

ということで、正解はどうやらこちららしい。
[python]
good = [[‘hogehoge’ for j in range(3)] for i in range(3)]
good
[[‘hogehoge’, ‘hogehoge’, ‘hogehoge’], [‘hogehoge’, ‘hogehoge’, ‘hogehoge’], [‘hogehoge’, ‘hogehoge’, ‘hogehoge’]]
good[2][2] = ‘egg’
good
[[‘hogehoge’, ‘hogehoge’, ‘hogehoge’], [‘hogehoge’, ‘hogehoge’, ‘hogehoge’], [‘hogehoge’, ‘hogehoge’, ‘egg’]]
[/python]

なんか、全く納得いかん。けど、そういうものだと割りきらないといけないみたい。
なぜ、こーなってしまうのか、知っている人いたら教えてください。

他の人はnumpyあたりかなーとかつぶやいてみたら、@tkfはやっぱりnumpy派らしい。ま、numpyでもよかったんだよね。なんで意地はっちゃったんだろう。中学生の恋みたい。