ズンドコで勉強する

  • 6
    Like
  • 17
    Comment
More than 1 year has passed since last update.

むしゃくしゃしてやった

zun.py
import random
def r(a, b):
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
try:
    r(4, 0)
except:
    print('キ・ヨ・シ!')

これで所期の結果が得られますが、exceptをfinallyにするとどうなるかというと。

zun_2.py
import random
def r(a, b):
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
try:
    r(4, 0)
finally:
    print('キ・ヨ・シ!')
finallyにしたときのメッセージ
ズン
ドコ
ズン
ズン
ズン
ズン
ドコ
キ・ヨ・シ!
Traceback (most recent call last):
  File "zun_2.py", line 5, in <module>
    r(4, 0)
  File "zun_2.py", line 3, in r
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 3, in r
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 3, in r
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 3, in r
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 3, in r
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 3, in r
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 3, in r
    r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
ZeroDivisionError: division by zero

これはちょっと馬鹿っぽい。。。
lambdaでやってもかわらない。

zun_2.py
import random
r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
try:
    r(4, 0)
finally:
    print('キ・ヨ・シ!')
結果の一部
Traceback (most recent call last):
  File "zun_2.py", line 4, in <module>
    r(4, 0)
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
  File "zun_2.py", line 2, in <lambda>
    r = lambda a,b: r(a-1, print('ズン')) if random.random() < 0.5 else r(4, print('ドコ') or 1/max(a,0))
ZeroDivisionError: division by zero

うーむ。。。
そういえば無名関数の再帰かけないのかなーと思って
http://fj.hatenablog.jp/entry/2014/06/15/032135
みたいな話を見かけたりしたが、性能は良くないらしい。

色々と綺麗にしたバージョン:

zun_3.py
import random
r=lambda a: print('ズン') or r(a-1) if random.random() < 0.5 else print('ドコ') or a <= 0 or r(4)
r(4) or print('キ・ヨ・シ!')

これは<=を==にすると、ちょうどズンが4つの場合以外はスルーするすぐれもの。5つ以上のズンを認めてよいかどうか、という議論はあってしかるべき。