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

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

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

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

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

PyPy

PyPy(パイパイ)は、RPythonで記述されたPythonの実装のひとつです。CPythonとの互換性に重点を置いて開発されており、コードを必要に応じて機械語にコンパイルする「JITコンパイル機能」を備えています。

Q&A

解決済

2回答

2927閲覧

Pythonで配列分割パターンの全通り列挙

Py_pp

総合スコア63

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

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

PyPy

PyPy(パイパイ)は、RPythonで記述されたPythonの実装のひとつです。CPythonとの互換性に重点を置いて開発されており、コードを必要に応じて機械語にコンパイルする「JITコンパイル機能」を備えています。

0グッド

0クリップ

投稿2020/02/21 06:51

前提・実現したいこと

Pythonで配列を2つに分けたときの全通りをリストする機能はありますでしょうか。

例:
[1,2,3,4]を渡したときに
[
[[1,2],[3,4]],
[[1,3],[2,4]],
[[1,4],[2,3]]
]

を取得したいです。
数字の重複は発生しません。

numpy.splitは前後でしか分割できないようです。

補足情報(FW/ツールのバージョンなど)

Python 3.7.3
を使用しています。

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

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

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

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

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

kirara0048

2020/02/21 12:10

要素数が奇数の場合はどうなりますか?
Py_pp

2020/02/22 05:28

すみません、要素数は偶数のみの想定でお願いします
guest

回答2

0

以下のようにできます。

  1. 2つのグループにおおよそ等しく分割するとする。

例: 要素数4 -> 2個、2個、要素数5 -> 2個、3個

  1. itertools.combinations で一方のグループのパターン (g1 とする) を列挙
  2. 配列から g1 を除いた要素がもう一方のグループ g2 となる。
  3. (g1, g2) の組み合わせから重複するものは削除する。

例: ((1, 2), (3, 4)) と ((3, 4), (1, 2)) は同じ
4.1. まずグループをソートする。g1, g2 if g1 < g2 else g2, g1
例: ((1, 2), (3, 4)) も ((3, 4), (1, 2)) もソート後は ((1, 2), (3, 4)) になる。
4.2. set() で重複を消す。

python

1from itertools import combinations 2 3 4def split(array): 5 n_group1 = len(array) // 2 # 2つのうち、一方のグループの個数 6 7 g1 = list(combinations(array, 2)) # グループ1 8 print(g1) # [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] 9 10 g2 = [tuple(set(array) - set(x)) for x in g1] # グループ2 11 print(g2) # [(3, 4), (2, 4), (2, 3), (1, 4), (1, 3), (1, 2)] 12 13 # 重複を除いた組み合わせ 14 pairs = set((x, y) if x < y else (y, x) for x, y in zip(g1, g2)) 15 pairs = list(pairs) 16 17 return pairs 18 19array = [1, 2, 3, 4] 20 21pairs = split(array) 22print(pairs) # {((1, 3), (2, 4)), ((1, 4), (2, 3)), ((1, 2), (3, 4))}

投稿2020/02/21 07:33

編集2020/02/21 07:36
tiitoi

総合スコア21956

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

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

kirara0048

2020/02/21 14:15

一行にしてみました pairs = [(x, tuple(set(array) - set(x))) for x in combinations(array, len(array)//2) if len(array)%2 or array[0] == x[0]]
kirara0048

2020/02/21 14:23

あと`set(array) - set(x)` は `set(array).difference(x)` の方がよさそうですね
tiitoi

2020/02/25 07:34

kirara0048 さん 1行で書くなら、そのような書き方もできますね。 コメントありがとうございます。
guest

0

ベストアンサー

組合せを使った方法です。
理想よりも2倍の列挙(走査)数かかりますが、結果は得られます。

Python

1import itertools 2 3lst = [1,2,3,4] 4d = {} 5s = set(lst) 6for c in itertools.combinations(s, 2): 7 8 t1 = tuple(sorted(c)) # 取ったもの 9 t2 = tuple(sorted(s - set(c))) # 残ったもの 10 11 # 小さいほうをキーとして重複を取り除く 12 k,v = (t1, t2) if t1 < t2 else (t2, t1) 13 d[k] = v 14 15for k,v in d.items(): 16 print(k,v) 17#(1, 2) (3, 4) 18#(1, 3) (2, 4) 19#(1, 4) (2, 3)

投稿2020/02/21 07:53

編集2020/02/21 08:13
can110

総合スコア38266

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問