Matplotlibやらscilabやらを使いたいが、cygwinでこれらを使えるようにするのは結構手間が掛かりそうなので、普通のWindows版を入れてみる。
http://www.python.org/download/ から、Python 2.6.5 Windows installerをダウンロード、実行。 (続く)
スライスでは、範囲外アクセスをしてもIndexErrorにはならない。
collections.defaultdictを使う。defaultdictの第1引数にはファクトリ関数を指定する。デフォルト値が0なら
collections.defaultdict(int)
デフォルト値が[]なら、
collections.defaultdict(list)
とすればよい。
def a1():
print "This is a1"
def a2():
global a1 # ←重要!!
def a3():
print "This is a3"
a1 = a3
a2()
a1()
コマンド"hoge"の出力結果をcommands.getoutput("hoge")で得られる。 実際には{ hoge ; } 2>&1と実行されるため、標準出力とエラー出力が混合される。 出力の最後の改行文字は取り除かれる。
os.environ['HOME']
タプル、リストの生成速度を比較してみる。 環境は以下の通り。
AMD Athlon 64X2 4400+ Python 2.6.5 (r265:79063, Jun 12 2010, 17:07:01) [GCC 4.3.4 20090804 (release) 1] on cygwin
>>> timeit.Timer("(1,)").timeit()
0.093999862670898438
>>> timeit.Timer("[1]").timeit()
0.44300007820129395
タプルが圧倒的に速い。 タプルはimmutableなので、このような定数リテラルの場合はオブジェクトを毎回生成しなくてよい。したがって、長さを長くしてみると
>>> timeit.Timer("(1,2,3,4,5,6,7,8,9)").timeit()
0.094000101089477539
>>> timeit.Timer("[1,2,3,4,5,6,7,8,9]").timeit()
0.63600015640258789
リストは遅くなるが、タプルは変わらない。
非定数の場合は以下のようになる。
>>> timeit.Timer("(n,n,n,n,n,n,n,n,n)","n=0").timeit()
0.32599997520446777
>>> timeit.Timer("[n,n,n,n,n,n,n,n,n]","n=0").timeit()
0.62599992752075195
やはりタプルの生成のほうがリストの生成よりも圧倒的に速いようだ。
要素数をさらに増やしてみると
>>> timeit.Timer("("+"n,"*1000+")","n=0").timeit(100000)
2.0319998264312744
>>> timeit.Timer("["+"n,"*1000+"]","n=0").timeit(100000)
2.2649998664855957
>>> timeit.Timer("(n,)*1000","n=0").timeit(100000)
0.59899997711181641
>>> timeit.Timer("[n,]*1000","n=0").timeit(100000)
0.77699995040893555
その差は縮まるが、やはりタプルが少し速い。
ある要素数のリストを作りたいとき、どうするか。 内容は後で代入するので、中身は問わない。 測定環境は以下の通り。
AMD Athlon 64X2 4400+ Python 2.6.5 (r265:79063, Jun 12 2010, 17:07:01) [GCC 4.3.4 20090804 (release) 1] on cygwin
n=100のとき、
方法1: [None] * n
>>> timeit.Timer("[None]*n","n=100").timeit()
1.6770000457763672
方法2: range(n) # 誤解を招くので、内容問わぬlist生成としては不適。多分Python3では使えない。
>>> timeit.Timer("range(n)","n=100").timeit()
2.253000020980835
方法3:リスト内包 timeit() = 2.89
>>> timeit.Timer("[None for i in xrange(n)]","n=100").timeit()
15.233000040054321
結論:[None] * nを使うべし。