あるデータを閾値で区切って処理しているときに、閾値ちょうどの値がそこそこあったりすると、上に入れるか下に入れるかで迷って、ならどっちもやってみてどう考えるのがいいか統計とってやればいいかと手を付けてみる。そのときに、python で 0,1,と閾値 を 2 として、 itertools.product を使ってみると
import itertools a=[0,2,0,1,2,2] b=[list(i) for i in itertools.product(*[[i] if i!=2 else [0,1] for i in a])] print(b) >>[[0, 0, 0, 1, 0, 0], >> [0, 0, 0, 1, 0, 1], >> [0, 0, 0, 1, 1, 0], >> [0, 0, 0, 1, 1, 1], >> [0, 1, 0, 1, 0, 0], >> [0, 1, 0, 1, 0, 1], >> [0, 1, 0, 1, 1, 0], >> [0, 1, 0, 1, 1, 1]]
となって戻ってきます。二次元リストにするのが便利なので、「itertools を使わずにできないか?」ということで、二次元リストの中のリストに値を append してやるとこれが予想したとおりにうまく動かない。検索しても二次元リストの中のリストに append するって解説はないみたいで色々やってみたのですが、+ でリストを連結していくのならうまくいきそうだったので、要素が一つのリストを作って、
a=[0,2,0,1,2,2] def product(a): n=a.count(2) c=[[]]*2**n nn=1 for cc in a: for j in range(2**n): jn=j//2**(n-nn)%2 if cc!=2: c[j]=c[j]+[cc] else: c[j]=c[j]+[jn] if j==len(range(2**n))-1: nn+=1 return c print(product(a)) >>[[0, 0, 0, 1, 0, 0], >> [0, 0, 0, 1, 0, 1], >> [0, 0, 0, 1, 1, 0], >> [0, 0, 0, 1, 1, 1], >> [0, 1, 0, 1, 0, 0], >> [0, 1, 0, 1, 0, 1], >> [0, 1, 0, 1, 1, 0], >> [0, 1, 0, 1, 1, 1]]
みたいな感じ。
じゃあ、複数データの選択肢が複数なら組み合わせをどうしようかってことで、得意技?の文字列変換でなんとかしてみることとした。
a=["a","b","c"] b=[0,1,2,3] c=["d","e","f"] d=[4,5] def test(*l): def test2(l1,l2): r=[] for ll1 in l1: for ll2 in l2: r.append(str(ll1)+","+str(ll2)) return r if len(l)==1: return l[0] elif len(l)==2: return test2(*l) elif len(l)>2: l1,l2,*l3=l return test(test2(l1,l2),*l3) print(test(a,b,c,d)) >>['a,0,d,4', >> 'a,0,d,5', >> 'a,0,e,4', >> 'a,0,e,5', >> 'a,0,f,4', >> 'a,0,f,5', >> 'a,1,d,4', >> 'a,1,d,5', >> 'a,1,e,4', >> 'a,1,e,5', >> 'a,1,f,4', >> 'a,1,f,5', >> 'a,2,d,4', >> 'a,2,d,5', >> 'a,2,e,4', >> 'a,2,e,5', >> 'a,2,f,4', >> 'a,2,f,5', >> 'a,3,d,4', >> 'a,3,d,5', >> 'a,3,e,4', >> 'a,3,e,5', >> 'a,3,f,4', >> 'a,3,f,5', >> 'b,0,d,4', >> 'b,0,d,5', >> 'b,0,e,4', >> 'b,0,e,5', >> 'b,0,f,4', >> 'b,0,f,5', >> 'b,1,d,4', >> 'b,1,d,5', >> 'b,1,e,4', >> 'b,1,e,5', >> 'b,1,f,4', >> 'b,1,f,5', >> 'b,2,d,4', >> 'b,2,d,5', >> 'b,2,e,4', >> 'b,2,e,5', >> 'b,2,f,4', >> 'b,2,f,5', >> 'b,3,d,4', >> 'b,3,d,5', >> 'b,3,e,4', >> 'b,3,e,5', >> 'b,3,f,4', >> 'b,3,f,5', >> 'c,0,d,4', >> 'c,0,d,5', >> 'c,0,e,4', >> 'c,0,e,5', >> 'c,0,f,4', >> 'c,0,f,5', >> 'c,1,d,4', >> 'c,1,d,5', >> 'c,1,e,4', >> 'c,1,e,5', >> 'c,1,f,4', >> 'c,1,f,5', >> 'c,2,d,4', >> 'c,2,d,5', >> 'c,2,e,4', >> 'c,2,e,5', >> 'c,2,f,4', >> 'c,2,f,5', >> 'c,3,d,4', >> 'c,3,d,5', >> 'c,3,e,4', >> 'c,3,e,5', >> 'c,3,f,4', >> 'c,3,f,5']
に
[[int(u) if u.isdigit() else u for u in t.split(",")] for t in test(a,b,c,d)]
こんな感じの噛ませればいいかと。
ちなみに Version
import sys print(sys.version) >> 3.10.11 (tags/v3.10.11:7d4cc5a, Apr 5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)]
なんかメイドインアビスみたいな画像と怪しい英語での煽り文句になっているみたいな気がするがまぁいいか。