LoginSignup
0
0

More than 3 years have passed since last update.

Pythonによるコレクションの前処理: 組み合わせ

Posted at
tests = ['A,B,C', 'D,E', 'A,C,E']

のようなデータがあったとき
これを要素別に
'A,B,C' -> ('A','B'),('A','C'),('B','C')
'D,E' -> ('D','E')
'A,C,E' -> ('A','C'),('A','E'),('C','E')
にしたい。

つまり以下のようにしたい。

[('A', 'B'),
 ('A', 'C'),
 ('B', 'C'),
 ('D', 'E'),
 ('A', 'C'),
 ('A', 'E'),
 ('C', 'E')]

要求を整理すると、testsの変数において、

  1. 各要素を配列にする
  2. 2つの組み合わせにする

をする方法をまとめる。

一行で書くと以下のようになる

list(itertools.chain.from_iterable([tuple(itertools.combinations(tuple(i.split(",")), 2)) for i in tests if len(i.split(",")) > 1]))

解説

各要素を配列にする

[tuple(i.split(",")) for i in tests if len(i.split(",")) > 1]
#  -> [('A', 'B', 'C'), ('D', 'E'), ('A', 'C', 'E')]

i.split(",") により要素1の配列しかできないものは、後続の処理で弾かれるためこの時点で弾いておく。

2つの組み合わせにする

[tuple(itertools.combinations(tuple(i.split(",")), 2)) for i in tests if len(i.split(",")) > 1]
# -> [(('A', 'B'), ('A', 'C'), ('B', 'C')),
# (('D', 'E'),),
# (('A', 'C'), ('A', 'E'), ('C', 'E'))]

itertools.combinationsを使用した。

この場合、リスト内包表記内で、「各要素を配列にする」の後に、itertools.combinations関数を利用する。結果としては配列中に、tupleが入ったような形になってしまっている。

これを解決するのにさらに、itertools.chain.from_iterable関数を利用する。(itertools.chain.from_iterable

よって以下のようになる。

list(itertools.chain.from_iterable([tuple(itertools.combinations(tuple(i.split(",")), 2)) for i in tests if len(i.split(",")) > 1]))
0
0
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
0
0