Pythonの変数はリファレンスという仕組みを使っている。
例えば
a = 1 b = 1
という代入文があったとしたら、これは変数aもbもおなじオブジェクト(数値の1)を参照しているという事だ。
なので
id(a) id(b)
を実行してみるとそれぞれ同じIDが出力されるはずだ。
その後
b = 2
とすれば変数bはオブジェクト(数値の2)を参照することになり
id(a) id(b)
を見てみるとここでは違ったIDが出力される。
では
a = 1 b = a
とした場合はどうだろうか?
Javascriptの配列で、ある要素がその配列に存在しているかを知りたい。
さらに存在するのであれば何番目に存在するのか?
といった時はindexOfメソッドが使えるが、ついつい間違ったコードを書いてしまいがちなのでここにメモしておく。
間違ったコードというのは
普段Macを使って作業をしているが、ちょっとしたプログラムを書いてテストするときはよくデスクトップに保存してからターミナルを起動する。chmod +xとして該当のプログラムファイルをドラッグし、実行の属性を与え、もう一度そのファイルをドラッグして実行。
テストプログラムを書く時はこれの繰り返しだ。
javascriptで数値を扱うときはMathオブジェクトを使う事で複雑な計算が出来るようになる。
たとえば
Rubyだと以下のような文が書ける
list1 = %w/taro hanako ryota hiroshi kotaro haruki kiyotaka jun/ list2 = list1.sort
これはlist1の配列を並べ替えた新規の配列list2を作成している。
list1は元の順番のまま何の変更も加えられていない。
さらに以下のような文も書ける
list1 = %w/taro hanako ryota hiroshi kotaro haruki kiyotaka jun/ list2 = list1.sort!
上の文との違いはsortの後ろに感嘆符(!)が付いているかいないかだけだが感嘆符がついた方はlist1自身を並べ替えてしまう。
つまりはlist1とlist2は同じ順番で並んだ全く同じ配列となる。
下のコードが何をしているか理解できるだろうか?
#!/opt/local/bin/perl use strict; use warnings; my @name1 = qw/yuta kenta koz ichiro masato manabu aiko/; my @name2 = qw/hiroshi motoo koz takeshi makoto manabu/; my %union = (); my %intersection = (); $union{$_}++ && $intersection{$_}++ for (@name1, @name2); my @union = keys %union; my @intersection = keys %intersection;
前回のエントリーで値を返す返さないとかいう事を書いたが、それが1番分かりやすいのがインタラクティブシェルだ。
Pythonの場合は引数なしで起動、Rubyはirbでそれぞれインタラクティブシェルが使える。
プログラミングを学び始めた頃は当然分からないことだらけで多分本を読んでも理解できない事の方が圧倒的に多い。
"式が値を返す"というのも最初は何の事だかいまいちピンとこなかった。
"関数が値を返す"というのは何となく分かりやすい、関数定義の中で
sub { my $name = shift; return $name; }
とすれば名前が返ってくるんだなと。
たとえば配列が2つ有って、その中で重複する値を知りたいとする。
片方は別に配列でなくてもいいのだが(ディレクトリハンドルが読み出すファイルのリスト等でもいい)要はその値が他方の配列の中に存在するかどうかを知りたいというのはよくある。
例えばRubyだとinclude?というメソッドがあるしPythonの場合in演算子というのが使える。
それぞれコードは
pythonのforループはいわゆるCのfor(for (int i; i < count; i++))なんかと違ってJavascriptのfor inループの様な書き方をする。
通常は多分問題になる事は無いがこのループだといわゆるindexを参照できない。要は今何番目の要素の処理をしているのかが分からない。
なので例えばPHPなんかで
Pythonでプログラミングをしていると他の言語に比べてなんか足りないなと思うことがしばしばある。
他のLL言語には配列を操作する関数(メソッド)でshiftというのがある。
配列の最初の要素を削除してその要素を返すという機能だがこれがPythonには無い。
Perlであればshift(@list)、PHPであればarray_shift($list)、Rubyならarray.shiftとそれぞれそろっているから当然Pythonにも、と思ったのだがいくら探しても見つからなかった。
ただ今日、ふと本を読んでいたら代替のメソッドが見つかった。list.pop()だ。このメソッドも同様に配列を操作するためのものだがshiftと違って配列の最後の要素を返すものだ。
それぞれPerlやPHPにも有るがPythonのそれは引数にインデックスを指定する事でどの要素を返すかを指定できるようになっている。
引数無しだと最後の要素、0を指定すると最初の要素を返す。
要はlist.pop(0)で他の言語のshiftの代わりになるという事だ。
なるほどこれで関数名を1つ節約できる訳だ。
たぶんpythonistaにしてみたら超基本的な事なんだろうなあ。
勉強になりました。