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」カテゴリの記事
- Noteの記事をPythonでバックアップしといた。(2021.05.05)
- JupyterLabでも好きな外部エディターを使いたい!(2018.05.02)
- ローカルエリア内のJupyterLabサーバーにLAN経由で接続する。(2018.05.02)
- Juliaやってみよう。五日目。Pythonと速度比較。(2017.08.01)
- Juliaやってみよう。四日目。@timeでプロファイリング(2017.07.16)
« Pythonのパッケージ、モデュールのアンインストール | トップページ | Holiday Sim攻略中。。 I haz a bucket!! »



コメント