Find all 3^4 permutation using lists

Solution 1:

There is simple and bruteforce, but working, example:

import itertools
import pprint

balls = set('1234')
splits = []
for i in range(0,len(balls)+1): # python ranges are upper-bound exclusive
    bucket_1_possibilities = (set(x) for x in itertools.combinations(balls,i))
    for bucket1 in bucket_1_possibilities:
        for j in range(0,len(balls)-i+1): # in the second cell there may be up to len(balls)-i balls 
            bucket_2_possibilities = list(set(x) for x in itertools.combinations(balls-bucket1,j))
            for bucket_2 in bucket_2_possibilities:
                splits.append([list(bucket1), list(bucket_2),list(balls-bucket1-bucket_2)])
pprint.pprint(splits)
print(len(splits))

Itertools.combinations (https://docs.python.org/3/library/itertools.html#itertools.combinations) allow you to get possible contents of first cell. From remaining balls you get possible contents of second cells, and so on.

Solution 2:

Instead of lists in list, a simpler interpretation is to think of a list of the balls position. See code below. The code is written in a lengthy way so that the logic is easy to follow.

combinations = []
for ball1 in range(3): # for all possible buckets we can put ball #1
    for ball2 in range(3): # for all possible buckets we can put ball #2
        for ball3 in range(3): # for all possible buckets we can put ball #3
            for ball4 in range(3): # for all possible buckets we can put ball #4
                ball_positions = [ball1, ball2, ball3, ball4]
                buckets = [[], [], []]
                for ball in range(4): # For each ball
                    bucket = ball_positions[ball] # This is the ball's position
                    buckets[bucket].append(ball) # So let's put the ball in this bucket
                combinations.append(buckets)                    

for i in range(len(combinations)): 
    print(i, combinations[i])

Solution 3:

You can use product from itertools to iterate over all combinations of several iterators. I think you are looking for something like this:

from itertools import product
main_list = []
for i,j,k,l in product(range(3),range(3),range(3),range(3)):
  sub_list = [[] for _ in range(3)]
  sub_list[i].append(1)
  sub_list[j].append(2)
  sub_list[k].append(3)
  sub_list[l].append(4)
  main_list.append(sub_list)
print(main_list)

or even more pythonic - replace product(range(3),range(3),range(3),range(3)) with product(*[range(3) for _ in range(4)]) and for better printing instead of print(main_list) use

for combination in main_list:
  print(*combination)