« Pythonのパッケージ、モデュールのアンインストール | トップページ | Holiday Sim攻略中。。 I haz a bucket!! »

2011年5月20日 (金)

PythonとMATLABのコピー、代入の違い。

MATLABからPython/numpyへ来くるといろいろと最初は違和感がある。例えば、スライスするときのシンタックスがちょっとなれるまで変な感じ。

MATLAB
a = [1:10]
b = a[2:end]
c = a[2:end-1]

Python
a = range(1,11)
b = a[1:]
c = a[1:-1]

0からインデックスが始まるのも注意。rangeもrange(10)とすると0から9までの10要素のリストが出来る。10で終わりたいのなら一つ多く指定するのを忘れがち。でもend書かなくっていいし、end-1よりは-1の方がすっきりするし、いまはnumpyの方がすきだ。

しかし、一番違和感があるのがこれじゃないだろうかとおもう。Pythonで上のコードのあとで

d = a
d[0] = 100

とするとaの内容も変更されてしまう。ためしにprintすると
print a[0]
100
となるはず。この説明が非常に分かりやすいページを見つけた。

http://henry.precheur.org/python/copy_list

つまり、Pythonではa = range(1,11)が意味するところは、1から10までのリストのオブジェクトにaというラベルをつけたのであって、代入しているわけではない。同様にd = aでもaというラベルが指定しているリストに別名が付いただけなのでちゃんとコピーしたいなら

d = list(a)

もしくは

d = a[:]

としないといけないわけだ。

これのNumpyバージョンは

a = numpy.arrange(1,11)
b = numpy.array(a)

という感じにnumpy.arrayで新しい配列をつくる宣言をする感じ。逆にリファレンスだけをコピーしたいならコピーのオプションをFalseにしてやる必要がある。copyはデフォルトではTrueなので上の例ではとくに書いていない。

b = numpy.array(a, copy=False)

追記)もっとスマートなのはTentative NumPy Tutorialにあるdeepcopyを使う方法。aがすでにnumpy arrayなのでそのアトリビュートであるcopyを呼んで:

b = a.copy()

これでdeepcopyされて、bに行われる操作はaに影響がない。

これ、整数値の場合はどうなるんだろう??とおもったけど基本的にはほしいタイプをもってきたらいいわけだから

e = 1
f = int(e)
f = 10
print e
1

のようにintでいいみたいだ。

なんでこういうデザインになっているのかはよくわからないんだけど、きっとメモリをやたら浪費しないような礼儀正しいコードを書くように強制しているのではないだろうか。。。インデントの作法が強制なおかげで人のコードが読み易くて非常にいいので、似たような感じかなぁ。。

« Pythonのパッケージ、モデュールのアンインストール | トップページ | Holiday Sim攻略中。。 I haz a bucket!! »

Python」カテゴリの記事

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: PythonとMATLABのコピー、代入の違い。:

« Pythonのパッケージ、モデュールのアンインストール | トップページ | Holiday Sim攻略中。。 I haz a bucket!! »

やっつけタイムライン

オススメたち

  • Librem One

    LibremOneでプライバシーを取り戻せ!VPN、eメール、チャット、ソーシャルメディア詰め合わせサービス

    follow us in feedly

    かなり更新が不定期なため、RSSリーダーをオススメします。RSSを表示

    超安定なLinux Mintを応援中



    超かっこいいジャズピアノ岩瀬章光

    Jenny Mayhem超おすすめ

    今読んでいる

2019年7月
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      

はてブ

無料ブログはココログ