無理矢理短く書いてみた
def squareSpiralX(): width = 0 (x,y) = (0,0) yield (0,0) phase = ((+1,0),(0,+1),(-1,0),(0,-1)) while True: for p in phase: if p[1] == 0: width += 1 for i in range(width): x += p[0] y += p[1] yield (x,y)
書いてみて,いくつかの欠点があることに気がつく
- ブロックネストの数が増えた
- if文がある
- 拡張代入の文(x += p[0],y += p[1])のうちどちらかは無意味になる
もとのコードでif文なしで状態遷移を表現しているところがおもしろいんだな.
実行効率も調べてみる
import profile >>> gx =squareSpiralX() >>> profile.run('for i in range(100000):xy = gx.next()') 100636 function calls in 1.280 CPU seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 633 0.000 0.000 0.000 0.000 :0(range) 1 0.000 0.000 0.000 0.000 :0(setprofile) 100000 0.570 0.000 0.570 0.000 <pyshell#40>:1(squareSpiralX) 1 0.710 0.710 1.280 1.280 <string>:1(?) 1 0.000 0.000 1.280 1.280 profile:0(for i in range(100000):xy = gx.next()) 0 0.000 0.000 profile:0(profiler) >>> g = squareSpiral() >>> profile.run('for i in range(100000):xy = g.next()') 100636 function calls in 1.090 CPU seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 633 0.020 0.000 0.020 0.000 :0(range) 1 0.000 0.000 0.000 0.000 :0(setprofile) 100000 0.470 0.000 0.490 0.000 <pyshell#33>:1(squareSpiral) 1 0.600 0.600 1.090 1.090 <string>:1(?) 1 0.000 0.000 1.090 1.090 profile:0(for i in range(100000):xy = g.next()) 0 0.000 0.000 profile:0(profiler)
2割弱処理時間が増えました.