開発環境
- OS: macOS High Sierra - Apple
- Text Editor: Emacs
- プログラミング言語: Python3
n重のfor文はその直積を取ることで1重にできることが知られている
— あいや🤘🙄🤘 (@public_ai000ya) 2018年7月31日
for i in 1..100
for j in 200..300
// (i, j) = (1, 200), (1, 201), .., (100, 300)
end
end
===
for (i, j) in (1..100 * 200..300)
// 上と同じ
end
同様のことをRuby(?)ではなくPythonではどのようにすればいいか気になったから書いてみた。
まず冗長な方法。
コード(Emacs)
#!/usr/bin/env python3 for i in range(1, 6): for j in range(20, 25): print((i, j))
入出力結果(Terminal, Jupyter(IPython))
$ ./sample.py (1, 20) (1, 21) (1, 22) (1, 23) (1, 24) (2, 20) (2, 21) (2, 22) (2, 23) (2, 24) (3, 20) (3, 21) (3, 22) (3, 23) (3, 24) (4, 20) (4, 21) (4, 22) (4, 23) (4, 24) (5, 20) (5, 21) (5, 22) (5, 23) (5, 24) $
リスト内包表記。
コード(Emacs)
#!/usr/bin/env python3 import pprint pairs = [(i, j) for i in range(1, 6) for j in range(20, 25)] pprint.pprint(pairs)
入出力結果(Terminal, Jupyter(IPython))
$ ./sample.py [(1, 20), (1, 21), (1, 22), (1, 23), (1, 24), (2, 20), (2, 21), (2, 22), (2, 23), (2, 24), (3, 20), (3, 21), (3, 22), (3, 23), (3, 24), (4, 20), (4, 21), (4, 22), (4, 23), (4, 24), (5, 20), (5, 21), (5, 22), (5, 23), (5, 24)] $
2重のfor文なら1重にはできてないものの、リスト内包表記で十分そう。
itertoolsモジュール(標準ライブラリー)のproductメソッドを利用した場合。
コード(Emacs)
#!/usr/bin/env python3 import pprint import itertools pairs = itertools.product(range(1, 6), range(20, 25)) pprint.pprint(list(pairs))
入出力結果(Terminal, Jupyter(IPython))
$ ./sample.py [(1, 20), (1, 21), (1, 22), (1, 23), (1, 24), (2, 20), (2, 21), (2, 22), (2, 23), (2, 24), (3, 20), (3, 21), (3, 22), (3, 23), (3, 24), (4, 20), (4, 21), (4, 22), (4, 23), (4, 24), (5, 20), (5, 21), (5, 22), (5, 23), (5, 24)] $
2重の場合リスト内包表記を利用した場合とあまり変わらない感じ。
nを5、すなわち5重の場合をリスト内包表記とitertoolsモジュールのproduct関数で記述。
コード(Emacs)
#!/usr/bin/env python3 import pprint import itertools print('リスト内包表記') t = [(i, j, k, l, m) for i in range(1, 6) for j in range(20, 25) for k in range(30, 35) for l in range(40, 45) for m in range(50, 55)] pprint.pprint(t[:10]) print('itertoolsモジュールのproductメソッド') s = itertools.product( range(1, 6), range(20, 25), range(30, 35), range(40, 45), range(50, 55) ) pprint.pprint(list(s)[:10])
入出力結果(Terminal, Jupyter(IPython))
$ ./sample.py リスト内包表記 [(1, 20, 30, 40, 50), (1, 20, 30, 40, 51), (1, 20, 30, 40, 52), (1, 20, 30, 40, 53), (1, 20, 30, 40, 54), (1, 20, 30, 41, 50), (1, 20, 30, 41, 51), (1, 20, 30, 41, 52), (1, 20, 30, 41, 53), (1, 20, 30, 41, 54)] itertoolsモジュールのproductメソッド [(1, 20, 30, 40, 50), (1, 20, 30, 40, 51), (1, 20, 30, 40, 52), (1, 20, 30, 40, 53), (1, 20, 30, 40, 54), (1, 20, 30, 41, 50), (1, 20, 30, 41, 51), (1, 20, 30, 41, 52), (1, 20, 30, 41, 53), (1, 20, 30, 41, 54)] $
for/in文の記述がいらないし、読みやすさの観点からも、nの値が大きければ大きいほどitertoolsモジュールのproductメソッドを使用した方が良さそう。
0 コメント:
コメントを投稿