やりたいこと
複数(例えば二つ)のリストから重複を避けて組み合わせをつくる.
ただし要素が同一のものも許すとする.
例えばa = [1, 2, 3, 4]
という配列があるとき.
a = [1, 2, 3, 4]
# このとき,こうしたい
result = [(1, 1), (1, 2), (1, 3), (1, 4),
(2, 2), (2, 3), (2, 4),
(3, 3), (3, 4)
(4, 4)]
よくある間違い
こういう時のためにitertools.product
があるんでしょと思って下のように書くと重複があることに気づく.
a = [1, 2, 3, 4]
print(list(itertools.product(a, repeat=2))
# 実行結果
[(1, 1), (1, 2), (1, 3), (1, 4),
(2, 1), (2, 2), (2, 3), (2, 4),
(3, 1), (3, 2), (3, 3), (3, 4)
(4, 1), (4, 2), (4, 3), (4, 4)]
(1, 2)
と(2, 1)
などが重複している.
だからと言ってcombinations
を使っても(1, 1)
とかの同一ペアが取り出せないしな...という葛藤
解決方法
リスト内の要素の組み合わせをitertools.combination
であらかじめ指定してから直積をとる.
ただし二重のitertools
なので実行速度的にはまずいのかもしれない.
# 二つ以上の組み合わせならcombinations第二引数の2を変えればよい
ans = []
for i, k in itertools.combinations(range(len(a)), 2):
for x, y in itertools.product(a[i], a[k]):
ans.append((x, y)]
print(ans)
# 実行結果
[(1, 1), (1, 2), (1, 3), (1, 4),
(2, 2), (2, 3), (2, 4),
(3, 3), (3, 4)
(4, 4)]
まとめ
正直言ってcombinations
よりも今回みたいに取り出したい時の方が多い気がするので,結構重宝するのではないかと思っている.
もっと早いやり方があったりしたら教えていたただきたいです.