LoginSignup
63
29

More than 1 year has passed since last update.

【Python】リスト内の要素の全ての組み合わせを出力

Last updated at Posted at 2019-12-12

リスト内の要素の組み合わせを全て知りたい
例えば

['Apple','Orange','Grape']

のリストから

[['Apple'], ['Orange'], ['Grape'], ['Apple', 'Orange'], ['Apple', 'Grape'], ['Orange', 'Grape'], ['Apple', 'Orange', 'Grape']]

という出力を得たいわけです。要素が1つしかない組み合わせもあるし、複数含まれる組み合わせもある。$2^n-1$個の要素をまとめたリストになることはわかるのですが、実際に書こうとしたら躓いてしまった。複雑なネストになりそうじゃないですか。

こういう時に使える標準ライブラリを知りました。
itertools --- 効率的なループ実行のためのイテレータ生成関数

イテレータ 引数 結果
combinations() p,r 長さrのタプル列、ソートされた順で重複なし

例えば、

test.py
import itertools

lis = [1,2,3,4]
for pair in itertools.combinations(lis, 2):
	print(pair)

上を実行すると以下の結果を得られます。

(1, 2)
(1, 3)
(1, 4)
(2, 3)
(2, 4)
(3, 4)

一応、引数を変えてもう一回試してみましょう。

test2.py
import itertools

lis = [1,2,3,4]
for team in itertools.combinations(lis, 3):
	print(team)
(1, 2, 3)
(1, 2, 4)
(1, 3, 4)
(2, 3, 4)

itertools.combinations() では、このようにリストの要素で、任意の要素数での全ての組み合わせパターンを(タプルで)得られます。
ここで、要素数を1からはじめてリスト長までfor文で回せば、最初に欲しかった答えが得られそうです。

all_combinations.py
import itertools

lis=['Apple','Orange','Grape']
result = []
for n in range(1,len(lis)+1):
	for conb in itertools.combinations(lis, n):
	    result.append(list(conb)) #タプルをリスト型に変換
print(result)

実行結果

[['Apple'], ['Orange'], ['Grape'], ['Apple', 'Orange'], ['Apple', 'Grape'], ['Orange', 'Grape'], ['Apple', 'Orange', 'Grape']]

『リーダブルコード』でも言及がありますが、普段から標準ライブラリに目を通す癖をつけておくと、良いコードを書けるんだろうなと思いました。

itertoolsについて他のメソッドも含めてまとめているQiitaの良記事がありますので参考に掲載します。

すごいぞitertoolsくん
itertools、more-itertoolsの紹介

便利だと思った標準ライブラリの紹介でした!

63
29
4

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
63
29