ループとイテレートの違いとは
Twitterで「ループや再帰なしで100万回Hello, World!するには?」というネタ?が少しだけ流行っていた。
Pythonの場合、for
やwhile
を使わない、という条件となる。
とはいえ、Pythonのアンパックを使えばそこまで難しくない。
docs.python.org
今回はBillion laughs攻撃の手法を使ってほんの少しだけいい感じに書く。
ja.wikipedia.org
a = "Hello World!"
b = [a, a, a, a, a, a, a, a, a, a]
c = [*b, *b, *b, *b, *b, *b, *b, *b, *b, *b]
d = [*c, *c, *c, *c, *c, *c, *c, *c, *c, *c]
e = [*d, *d, *d, *d, *d, *d, *d, *d, *d, *d]
f = [*e, *e, *e, *e, *e, *e, *e, *e, *e, *e]
g = [*f, *f, *f, *f, *f, *f, *f, *f, *f, *f]
xx = tuple(map(lambda x: print(x), g))
print(len(xx))
考察
確かに、for
文やwhile
文は使っていない。
また、再帰も使っていない。
しかし、アンパックする際に内部的にイテレータを使っているので、「ループを使わない」という条件を満たしているのかどうかは疑問が残る。
イテラブルオブジェクトのアンパックは注意が必要である。
今回は(10倍ずつ増える、つまり指数函数的に増大する)有限のリストだが、これを無限に続くジェネレータに対して行うと途端に破綻する。
自分が何をアンパックしているのかを気にしながら使うようにすべきである。