Python combines combinations of 8 objects into 3 groups, 3-3-2

Let's say I have a list of 8 objects, numbered 1-8.

Objects are placed in three fields, 3 in one box, 3 in another, 2 in the last field. In mathematics, there are 8C3 * 5C3 = 560 ways to do this. I want to skip 560 elements there. Is there a way in Python to do this?

The result should look like this:

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

Please note that ['12','345','678'] and ['12','354',876'] are considered the same for this purpose.

I want to make this loop for a loop. Is there a way in Python to do this?

Here is the solution I get, but it seems ugly.

 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) 
+6
source share
3 answers
 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'] 

Another example:

 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'] 
+2
source

You can simply rearrange all of your 8 values ​​(as shown in previous answers). to do this, use this previous answer (also by the following code).

Then designate each combination as a tuple so that they can be hashed and unique, for this you will have to order them so that they can also be uniquely matched.

 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 

For your example, with 8 values, this gives 560 combinations.

0
source

l will be a list of eight objects, in this example the line:

 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 and a 2 print(group) 

It produces:

 >>> ['O1', '02', '03'] ['04', '04', '06'] ['07','08'] 
-1
source

Source: https://habr.com/ru/post/944094/


All Articles