2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

itertoolsで一つのリストから要素が同一のものも含めて重複を避けて組み合わせを作る

Posted at

やりたいこと

複数(例えば二つ)のリストから重複を避けて組み合わせをつくる.
ただし要素が同一のものも許すとする.
例えば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よりも今回みたいに取り出したい時の方が多い気がするので,結構重宝するのではないかと思っている.
もっと早いやり方があったりしたら教えていたただきたいです.

2
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?