質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

5041閲覧

python3 組み合わせについて(重複なし)

Sayre

総合スコア23

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/08/21 02:31

お世話になっております。
重複なしの組み合わせのプログラムを作成しております。
下記のようなことを実装できるモジュールを作成したいのですが、
プログラム自体初学者故考えが及ばないので、質問させてもらいます。

['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']

上記リストを[2,3,4]といった値を与えられたときに
9C2 * 7C3 * 4C4といった重複なしの組み合わせのリストを作成できるモジュールを作りたいです。

例)
[[['a', 'b'], ['c', 'd', 'e'], ['f', 'g', 'h', 'i']], [['a', 'b'], ['c', 'd', 'f'], ['e', 'g', 'h', 'i']], [['a', 'b'], ['c', 'd', 'g'], ['e', 'f', 'h', 'i']], ...

python

1def comb(a,b) #aに[2,3,4]や[5,4],[6,3]等が入る想定。bには文字列のリスト

combinationsを使用して、9C2,7C3,4C4それぞれの組み合わせを表示するだけなら出来ましたが、
そこから上記例のようなリストにまとめることができません。

ぜひご回答頂ければと思います。よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

再帰で書くと比較的簡潔に書けるかと思います。

Python

1import itertools 2 3# a : 各組合せ数のリスト 4# b : 組み合わせる要素リスト 5# l : 途中までの結果リスト 6# lv : 現在の組み合わせ数の位置 7# 8def comb(a, b, l, lv): 9 if not b: 10 print(l) # 最終結果をリストとして保持したいなら、このlをグローバルに用意したリストなりに追加すればよい 11 return 12 13 for ret in itertools.combinations(b, a[lv]): 14 lc = l.copy() 15 lc.append(ret) 16 comb(a, b - set(ret), lc, lv + 1) 17 18a = [2, 3, 4] 19b = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'] 20 21#a = [2, 3] 22#b = ['a', 'b', 'c', 'd', 'e'] 23comb(a, set(b), [], 0)

投稿2019/08/21 03:53

編集2019/08/21 03:56
can110

総合スコア38262

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Sayre

2019/08/21 05:46

回答ありがとうございます。 実際に欲しい値が出力されることを確認しました。 また一つ教えていただきたいのですが、もしcombの関数の引数が 二つしか取れない場合(aとbのみ)はどうすればよろしいでしょうか?
can110

2019/08/21 05:48 編集

なぜそのような制約がある(必要?)のでしょうか?
Sayre

2019/08/21 05:53

完全に個人的な話になってしまい申し訳ありませんが、 プライベートで取り組んでいるpythonの問題にそのような制約があるためです。。
can110

2019/08/21 05:58

課題的な問題でしたらヒントだけ示します。 グローバルな変数を使うのもひとつの手です。 あまりエレガントではないですが。。
Sayre

2019/08/22 04:44

ありがとうございます。 グローバルな変数を使ってみます。
guest

0

全体の順列を取って、スライスで分割するのが楽だと思います。

Python

1import itertools 2 3 4src = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'] 5 6for b in itertools.permutations(src): 7 b = b[:2], b[2:5], b[5:] 8 print(b)

実行結果(抜粋) Wandbox

(('a', 'b'), ('c', 'd', 'e'), ('f', 'g', 'h', 'i')) (('a', 'b'), ('c', 'd', 'e'), ('f', 'g', 'i', 'h')) (('a', 'b'), ('c', 'd', 'e'), ('f', 'h', 'g', 'i')) ... (('a', 'c'), ('b', 'd', 'e'), ('f', 'g', 'h', 'i')) (('a', 'c'), ('b', 'd', 'e'), ('f', 'g', 'i', 'h')) (('a', 'c'), ('b', 'd', 'e'), ('f', 'h', 'g', 'i')) ...

ただしこの場合処理が 9! = 362880 回繰り返されるので、現実的であるかは微妙です。

投稿2019/08/21 02:55

LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Sayre

2019/08/21 04:07

解答ありがとうございます。 今回は重複はなしで考えたいので順列ではない想定です。 なので、今回[2,3,4]の組み合わせを考える場合、 9C2 * 9C3* 9C4 = 1260通りになる想定です。
LouiS0616

2019/08/21 04:42

ああ、内側のリストの要素は順を問わないのですね。 それならば確かに 9! / (2! x 3! x 4!) で 1260通りです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問