2013-05-02 41 views
5

Giả sử tôi có danh sách 8 đối tượng, đánh số 1-8.Kết hợp lặp vòng lặp của 8 đối tượng thành 3 nhóm, 3-3-2

Các đối tượng được đưa vào ba hộp, 3 trong một hộp, 3 trong một hộp khác, 2 trong hộp cuối cùng. Theo toán học, có 8C3 * 5C3 = 560 cách để làm điều này. Tôi muốn lặp qua đó 560 mục. Có cách nào trong Python làm như vậy không?

Kết quả sẽ giống như thế này:

list=['12','345',678'], ['12','346','578'], ..., etc. 

Lưu ý rằng ['12','345','678']['12','354',876'] được coi là tương tự cho mục đích này.

Tôi muốn tạo danh sách cho vòng lặp này. Có cách nào trong Python để làm như vậy?

Đây là giải pháp tôi nhận được, nhưng có vẻ như xấu xí.

import itertools 
for c1,c2 in itertools.combinations(range(8),2): 
      l2=list(range(8)) 
      l2.pop(c2) 
      l2.pop(c1) 
      for c3,c4,c5 in itertools.combinations(l2,3): 
       l3=l2[:] 
       l3.remove(c5) 
       l3.remove(c4) 
       l3.remove(c3) 
       c6,c7,c8=l3 
       print(c1,c2,c3,c4,c5,c6,c7,c8) 
+1

bạn đã cố gắng giải quyết nó như thế nào? Mã gì? – snapshoe

+0

Bạn có thể itertools http://docs.python.org/2/library/itertools.html và thêm một số logic của riêng bạn. – Pramod

+0

Tôi phải nói rằng tôi không thực sự hiểu câu hỏi của bạn. –

Trả lời

2
def F(seq, parts, indexes=None, res=[], cur=0): 
    if indexes is None: # indexes to use for combinations 
     indexes = range(len(seq)) 

    if cur >= len(parts): # base case 
     yield [[seq[i] for i in g] for g in res] 
     return  

    for x in combinations(indexes, r=parts[cur]): 
     set_x = set(x) 
     new_indexes = [i for i in indexes if i not in set_x] 
     for comb in F(seq, parts, new_indexes, res=res + [x], cur=cur + 1): 
      yield comb 

it = F('12345678', parts=(2,3,3)) 
for i in range(10): 
    print [''.join(g) for g in next(it)] 

['12', '345', '678'] 
['12', '346', '578'] 
['12', '347', '568'] 
['12', '348', '567'] 
['12', '356', '478'] 
['12', '357', '468'] 
['12', '358', '467'] 
['12', '367', '458'] 
['12', '368', '457'] 
['12', '378', '456'] 

Một ví dụ khác:

for c in F('1234', parts=(2,2)): 
    print [''.join(g) for g in c] 

['12', '34'] 
['13', '24'] 
['14', '23'] 
['23', '14'] 
['24', '13'] 
['34', '12'] 
+0

Tôi nhận được IndexError: danh sách chỉ mục nằm ngoài phạm vi khi chạy mã. – Pramod

+0

Câu trả lời hay, tôi không hiểu tại sao điều này không được bình chọn! – Werner

-1

l sẽ là một danh sách tám đối tượng, trong ví dụ này chuỗi:

l = ["O1","02","03","04","04","06","07","08"] 
for group in [l[:3],l[3:6],l[6:]]: #get 3 slices of the list into 3's and a 2 
    print(group) 

Tạo:

>>> 
['O1', '02', '03'] 
['04', '04', '06'] 
['07','08'] 
0

Bạn chỉ có thể hoán vị tất cả 8 giá trị của bạn (như hiển thị trên câu trả lời trước). để sử dụng điều này previous answer (cũng có trên mã sau).

Sau đó gán từng kết hợp làm bộ tuple, để chúng có thể được băm và duy nhất, bạn sẽ phải đặt hàng chúng, vì vậy chúng cũng có thể được so sánh độc đáo.

def all_perms(elements): 
    if len(elements) <=1: 
     yield elements 
    else: 
     for perm in all_perms(elements[1:]): 
      for i in range(len(elements)): 
       #nb elements[0:1] works in both string and list contexts 
       yield perm[:i] + elements[0:1] + perm[i:] 


v = [1,2,3,4,5,6,7,8] 

a = {} 
for i in all_perms(v): 
    k = (tuple(sorted([i[0],i[1]])) , tuple(sorted([i[2],i[3],i[4]])) , tuple(sorted([i[5],i[6],i[7]]))) 

    if k not in a: 
     a[k] = [str(i[0])+str(i[1]), str(i[2])+str(i[3])+str(i[4]), str(i[5])+str(i[6]) + str(i[7])] 

x = 0 
for i in a.values(): 
    print x, i 
    x+=1 

Ví dụ của bạn về 8 giá trị, điều này cho 560 kết hợp.

+0

không theo thứ tự của OP mặc dù (không chắc chắn nếu có vấn đề) – jamylak

+0

thứ tự của OP là gì? – eLRuLL

+0

anh ấy đã xóa vì lý do nào đó, nó đã trở lại trong câu hỏi ngay bây giờ – jamylak