2013-05-02 10 views
5

Załóżmy, że mam listę 8 obiektów o numerach od 1-8.Python zapętla kombinacje 8 obiektów w 3 grupach, 3-3-2

Obiekty są umieszczane w trzech polach, 3 w jednym pudełku, 3 w innym pudełku, 2 w ostatnim polu. Według matematyki jest 8C3 * 5C3 = 560 sposobów na zrobienie tego. Chcę przelecieć tam 560 pozycji. Czy jest jakiś sposób w Pythonie, aby to zrobić?

Wynik powinien wyglądać następująco:

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

Zauważ, że ['12','345','678'] i ['12','354',876'] są traktowane tak samo do tego celu.

Chcę zrobić pętlę do tej listy. Czy jest jakiś sposób w Pythonie, aby to zrobić?

Oto rozwiązanie, które otrzymuję, ale wydaje się brzydkie.

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

Jak próbowałeś go rozwiązać? jaki kod? – snapshoe

+0

Możesz itertools http://docs.python.org/2/library/itertools.html i dodać trochę swojej własnej logiki. – Pramod

+0

Muszę powiedzieć, że tak naprawdę nie rozumiem twojego pytania. –

Odpowiedz

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'] 

Inny przykład:

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

Otrzymuję IndexError: indeks listy poza zakresem podczas uruchamiania kodu. – Pramod

+0

Świetna odpowiedź, nie rozumiem, dlaczego nie jest to przegłosowane! – Werner

-1

L będzie listę ośmiu obiektów, w tym przykładzie struny

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) 

Wytwarza:

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

Można tylko permutacji wszystkie wartości 8 (jak pokazano w poprzednich odpowiedziach). do tego użyj tego previous answer (również pod poniższym kodem).

Następnie przypisz każdą kombinację jako krotkę, aby mogły być mieszane i unikatowe, ponieważ musisz je zamówić, aby można je było również porównywać w unikalny sposób.

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 

Dla przykładu na 8 wartościach daje to 560 kombinacji.

+0

nie na zamówienie OP (nie wiem, czy to ma znaczenie) – jamylak

+0

jakie jest zamówienie OP? – eLRuLL

+0

usunął go z jakiegoś powodu, teraz wraca do pytania – jamylak