はじめに
移植やってます。
( from python 3.7 to ruby 2.7 )
product (Python)
import itertools
A = [('a', 'b', 'c'), ('d', 'e'), ('f', 'g')]
print(list(itertools.product(*A)))
# [('a', 'd', 'f'), ('a', 'd', 'g'), ('a', 'e', 'f'), ('a', 'e', 'g'), ('b', 'd', 'f'), ('b', 'd', 'g'), ('b', 'e', 'f'), ('b', 'e', 'g'), ('c', 'd', 'f'), ('c', 'd', 'g'), ('c', 'e', 'f'), ('c', 'e', 'g')]
ジェネレータ式の入れ子になった for ループとおよそ等価です。たとえば product(A, B) は ((x,y) for x in A for y in B) と同じものを返します。
ふむふむ。
product 失敗 (Ruby)
A = [['a', 'b', 'c'], ['d', 'e'], ['f', 'g']]
print(A.inject(:product))
# [[["a", "d"], "f"], [["a", "d"], "g"], [["a", "e"], "f"], [["a", "e"], "g"], [["b", "d"], "f"], [["b", "d"], "g"], [["b", "e"], "f"], [["b", "e"], "g"], [["c", "d"], "f"], [["c", "d"], "g"], [["c", "e"], "f"], [["c", "e"], "g"]]
単に、inject
すると、平坦化されていない状態で出力されます。
product + flatten 成功 (Ruby)
A = [['a', 'b', 'c'], ['d', 'e'], ['f', 'g']]
print(A.inject(:product).map(&:flatten))
# [["a", "d", "f"], ["a", "d", "g"], ["a", "e", "f"], ["a", "e", "g"], ["b", "d", "f"], ["b", "d", "g"], ["b", "e", "f"], ["b", "e", "g"], ["c", "d", "f"], ["c", "d", "g"], ["c", "e", "f"], ["c", "e", "g"]]
tuple
ではないのですが、同様の処理ができました。
product 応用問題 (Python)
import itertools
A = [(('H-', 'a'), 'b', 'c'), ('d', 'e'), ('f', 'g')]
print(list(itertools.product(*A)))
# [(('H-', 'a'), 'd', 'f'), (('H-', 'a'), 'd', 'g'), (('H-', 'a'), 'e', 'f'), (('H-', 'a'), 'e', 'g'), ('b', 'd', 'f'),
('b', 'd', 'g'), ('b', 'e', 'f'), ('b', 'e', 'g'), ('c', 'd', 'f'), ('c', 'd', 'g'), ('c', 'e', 'f'), ('c', 'e', 'g')]
前回は、要素が一つずつでしたが、今回は要素数が異なります。
product 応用問題 (Ruby)
A = [[['H-', 'a'], 'b', 'c'], ['d', 'e'], ['f', 'g']]
print(A.inject(:product).map(&:flatten))
# [["H-", "a", "d", "f"], ["H-", "a", "d", "g"], ["H-", "a", "e", "f"], ["H-", "a", "e", "g"], ["b", "d", "f"], ["b", "d", "g"], ["b", "e", "f"], ["b", "e", "g"], ["c", "d", "f"], ["c", "d", "g"], ["c", "e", "f"], ["c", "e", "g"]]
print(A.inject(:product).map{ _1.flatten(1) }) # 1
print(A[0].product(*A[1..-1])) # 2
# [[["H-", "a"], "d", "f"], [["H-", "a"], "d", "g"], [["H-", "a"], "e", "f"], [["H-", "a"], "e", "g"], ["b", "d", "f"], ["b", "d", "g"], ["b", "e", "f"], ["b", "e", "g"], ["c", "d", "f"], ["c", "d", "g"], ["c", "e", "f"], ["c", "e", "g"]]
単なるflatten
ですと平坦化しすぎですので、深さを指定します。
2番目の書き方は、こちらを参照しました。
メモ
- Python の itertools.product を学習した
- 百里を行く者は九十里を半ばとす