2012-05-12 7 views
2

シーケンスをペアに分割し、組み合わせのすべての要素が一意になるように組み合わせる必要があります。私はpythonのitertoolsを使用していくつかのアプローチを試しましたが、解決策は見つかりませんでした。 [1、2、3 4] シーケンスを一意のペアのセットに分割する

と以下の3つの組み合わせに分割:私はこのシーケンスを取る機能を希望例示する

[[1, 2], [3, 4]] 
[[1, 3], [2, 4]] 
[[1, 4], [2, 3]] 

それがなければならない、またより長いシーケンスのために働くが、奇数の長さのシーケンスを処理する必要はない。例えば。以下の15個の組み合わせに

[1,2,3,4,5,6] 

分割:

[[1, 2], [3, 4], [5, 6]] 
[[1, 2], [3, 5], [4, 6]] 
[[1, 2], [3, 6], [4, 5]] 
[[1, 3], [2, 4], [5, 6]] 
[[1, 3], [2, 5], [4, 6]] 
[[1, 3], [2, 6], [4, 5]] 
[[1, 4], [2, 3], [5, 6]] 
[[1, 4], [2, 5], [3, 6]] 
[[1, 4], [2, 6], [3, 5]] 
[[1, 5], [2, 3], [4, 6]] 
[[1, 5], [2, 4], [3, 6]] 
[[1, 5], [2, 6], [3, 4]] 
[[1, 6], [2, 3], [4, 5]] 
[[1, 6], [2, 4], [3, 5]] 
[[1, 6], [2, 5], [3, 4]] 

...というように。

Mapleと呼ばれるCASには、この機能がsetpartitionという名前で実装されています。

編集:wksによって指摘された深刻な深夜のタイピングエラーを修正し、出力を明確にしました。

+2

あなたは[[1,2]、[3,4]]を意味しましたか? – wks

+1

はい、私は非常に疲れているに違いない。 – FrederikNS

答えて

5

itertoolsは確かにあなたの友人である:

from itertools import permutations 

def group(iterable, n=2): 
    return zip(*([iter(iterable)] * n)) 

for each in permutations([1, 2, 3, 4, 5, 6]): 
    print map(list, group(each)) 

結果:

[[1, 2], [3, 4], [5, 6]] 
[[1, 2], [3, 4], [6, 5]] 
[[1, 2], [3, 5], [4, 6]] 
[[1, 2], [3, 5], [6, 4]] 
[[1, 2], [3, 6], [4, 5]] 
[[1, 2], [3, 6], [5, 4]] 
[[1, 2], [4, 3], [5, 6]] 
[[1, 2], [4, 3], [6, 5]] 
[[1, 2], [4, 5], [3, 6]] 
... 

[EDIT] @FrederikNS:あなたがあなたの質問and found an answer yourselfを明らかにした後、ここに私の解決策は次のとおりです。

from itertools import combinations 

def setpartition(iterable, n=2): 
    iterable = list(iterable) 
    partitions = combinations(combinations(iterable, r=n), r=len(iterable)/n) 
    for partition in partitions: 
     seen = set() 
     for group in partition: 
      if seen.intersection(group): 
       break 
      seen.update(group) 
     else: 
      yield partition 

for each in setpartition([1, 2, 3, 4]): 
    print each 
print 
for each in setpartition([1, 2, 3, 4, 5, 6]): 
    print each 

結果:私は最終的にそれを私の自己を得た

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

((1, 2), (3, 4), (5, 6)) 
((1, 2), (3, 5), (4, 6)) 
((1, 2), (3, 6), (4, 5)) 
((1, 3), (2, 4), (5, 6)) 
((1, 3), (2, 5), (4, 6)) 
((1, 3), (2, 6), (4, 5)) 
((1, 4), (2, 3), (5, 6)) 
((1, 4), (2, 5), (3, 6)) 
((1, 4), (2, 6), (3, 5)) 
((1, 5), (2, 3), (4, 6)) 
((1, 5), (2, 4), (3, 6)) 
((1, 5), (2, 6), (3, 4)) 
((1, 6), (2, 3), (4, 5)) 
((1, 6), (2, 4), (3, 5)) 
((1, 6), (2, 5), (3, 4)) 
+0

これは素晴らしいです。 –

+0

+1これは素晴らしいですが、他の言語の言語構造として混乱する可能性があるので、私は名前として 'each 'の使用が嫌いです。 – jamylak

+0

これはクールですが、残念ながら私が行っていたものではありません。私はさらに質問を明確にしました。 – FrederikNS

0

はこれを試してみてください:

def function(list): 
    combinations = [] 
    for i in list: 
     for i2 in list: 
      if not [i2, i] in combinations: 
       combinations.append([i, i2]) 
    return combinations 

これは、すべての可能な組み合わせを返します。

希望すると便利です。

+2

これは問題が望んでいたものではありません。この例の余分なグループ化を参照してください。あなたはitertools.combinationsを書き直しました –

1

は(pillmuncherの答えは本当に私の右方向にナッジを与え、グループ機能は完全に彼のです):

def group(iterable, n=2): 
    return zip(*([iter(iterable)] * n)) 

def set_partition(iterable, n=2): 
    set_partitions = set() 

    for permutation in itertools.permutations(iterable): 
     grouped = group(list(permutation), n) 
     sorted_group = tuple(sorted([tuple(sorted(partition)) for partition in grouped])) 
     set_partitions.add(sorted_group) 

    return set_partitions 

partitions = set_partition([1,2,3,4], 2) 
for part in partitions: 
    print(part) 

この版画:

((1, 4), (2, 3)) 
((1, 3), (2, 4)) 
((1, 2), (3, 4)) 
関連する問題