2017-05-15 5 views
-1

itertools.cycleと一致するitertools.combinationsを使用して、別のオブジェクトリストに割り当てるオブジェクトのセットを作成しています。悲しいことに、リストが同じ長さでないか、または均等に割り切れる場合、リストの最初の項目は不均一に重み付けされます。分散 `itertools.combinations`

cycle_of_combinations = cycle(combinations(['A', 'B', 'C', 'D'], 2)) 
#(('A', 'B'), 
# ('A', 'C'), 
# ('A', 'D'), 
# ('B', 'C'), 
# ('B', 'D'), 
# ('C', 'D')) 

assigned_combinations = [] 
for _ in range(0, 9): 
    assigned_combinations.append(cycle_of_combinations.next()) 

# assigned_combinations = [ 
# ('A', 'B'), 
# ('A', 'C'), 
# ('A', 'D'), 
# ('B', 'C'), 
# ('B', 'D'), 
# ('C', 'D'), 
# ('A', 'B'), 
# ('A', 'C'), 
# ('A', 'D')] 

上記の例では、 'A'を含む組み合わせは過度に表現されています。組み合わせをより均等に分散するための迅速な方法はありますか?

ここでは9つの項目があるまで、このセットでは、私はすべての第2項目を選択した、より均一に分布されるだろうセットの例です:

# assigned_combinations = [ 
# ('A', 'B'), 
# ('A', 'D'), 
# ('B', 'D'), 
# ('A', 'C'), 
# ('B', 'C'), 
# ('C', 'D'), 
# ('A', 'B'), 
# ('A', 'D'), 
# ('B', 'D')] 
+1

@ user2357112どのようにカウントしていますか? 「B」、「C」、「D」の6つの組み合わせのうち、6つの組み合わせのうち3つで6つの組み合わせのうち3つに「A」が表示されます。 –

+0

なぜ6番目の要素で 'assigned_combinations'を切断しましたか?それはあなたが止めようとしている効果を混乱させるものです。 – user2357112

+0

同様に、 'cycle'の中のあなたのコメントは、実際にサイクルを作成したという事実を隠します(また、その変数に' cycle'という名前をつけて、あなたがインポートした 'cycle'関数を隠しています)。 – user2357112

答えて

1

はあなたが必要をカバーするのに十分な完全なサイクルを生成することがありましたリストを作成し、シャッフルしてサイズ調整を行います。返されるリストは毎回少しずつ異なりますが、あなたはまだ表現を超えてしまいます(サイズの不一致が避けられず、random.shuffleは時折それをより顕著にするかもしれません)。

import math 
import itertools 
import random 

def get_combos(somelist, length, count): 
    combos = list(itertools.combinations(somelist, length)) 
    combos = combos * math.ceil(count/len(combos)) 
    random.shuffle(combos) 
    return combos[:count] 

for item in get_combos(['A', 'B', 'C', 'D'], 2, 9): 
    print(item)