0

I am trying to make a list of all possible 27 3-character permutations of RGB. My function is as follows:

def make_big_RGB():
    rgb = ('r', 'g', 'b')
    comb_list = []
    current_combination = list(rgb) #start with combination (r, g, b)
    for x in range(3):
        current_combination[0] = rgb[x]
        for y in range(3):
            current_combination[1] = rgb[y]
            for z in range(3):
                current_combination[2] = rgb[z]
                comb_list.append(current_combination)
                print('Added' + str(current_combination))
    for _ in comb_list:
        print(_)
make_big_RGB()

The result is as follows:

Added['r', 'r', 'r']
Added['r', 'r', 'g']
Added['r', 'r', 'b']
Added['r', 'g', 'r']
Added['r', 'g', 'g']
Added['r', 'g', 'b']
Added['r', 'b', 'r']
Added['r', 'b', 'g']
Added['r', 'b', 'b']
Added['g', 'r', 'r']
Added['g', 'r', 'g']
Added['g', 'r', 'b']
Added['g', 'g', 'r']
Added['g', 'g', 'g']
Added['g', 'g', 'b']
Added['g', 'b', 'r']
Added['g', 'b', 'g']
Added['g', 'b', 'b']
Added['b', 'r', 'r']
Added['b', 'r', 'g']
Added['b', 'r', 'b']
Added['b', 'g', 'r']
Added['b', 'g', 'g']
Added['b', 'g', 'b']
Added['b', 'b', 'r']
Added['b', 'b', 'g']
Added['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']
['b', 'b', 'b']

The last for loop prints out the wanted result, but when I subsequently try to print the whole list, the result is somehow a list of 27 items of [b, b, b]. I don't understand why.

Hallvard
  • 191
  • 1
  • 1
  • 7
  • 2
    You've appended 27 references to the one `current_combination` list object to `comb_list`. – PM 2Ring Feb 08 '18 at 13:44
  • 1
    jp's solution is good. But just in case you want to keep your code, changing the line where you append to this: `comb_list.append(current_combination.copy())` should work as well. – Arne Feb 08 '18 at 13:44
  • 2
    There aren't 27 permutations of RGB. There are 27 3-character combinations. There are 6 permutations. – khelwood Feb 08 '18 at 13:47
  • Possible duplicate of [generating permutations with repetitions in python](https://stackoverflow.com/questions/3099987/generating-permutations-with-repetitions-in-python) – Georgy Feb 08 '18 at 13:55
  • 1
    You keep modifying the same `current_combination` list object and appending a reference to that _one_ object to `comb_list`. So when you print `comb_list` all you'll see is 27 copies of whatever the current contents of `current_combination` are. – PM 2Ring Feb 08 '18 at 14:00
  • 1
    Try this: put `current_combination[:] = 'xyz'` just after the end of your main loops but before your `for _ in comb_list:` printing loop. The code will then print 27 lines of `['x', 'y', 'z']` – PM 2Ring Feb 08 '18 at 14:04
  • 2
    @Georgy Sure, your linked question shows how to get the Cartesian product. But it doesn't address the Hallvard's main question: why does `comb_list` end up containing a bunch of duplicate sublists? – PM 2Ring Feb 08 '18 at 14:07
  • Here's a very closely related question: https://stackoverflow.com/questions/5280799/list-append-changing-all-elements-to-the-appended-item – PM 2Ring Feb 08 '18 at 14:34
  • @khelwood After doing a little recap, I think you’ve got the two mixed up – Hallvard Feb 09 '18 at 00:38
  • @khelwood I agree that there are 6 permutations of the set RGB, but likewise there are 27 3-character permutations, and 10 3-character combinations:['r', 'r', 'r'] ['b', 'b', 'b'] ['g', 'g', 'g'] ['r', 'g', 'b'] ['r', 'r', 'g'] ['r', 'r', 'b'] ['r', 'g', 'g'] ['g', 'g', 'b'] ['r', 'b', 'b'] ['g', 'b', 'b']) – Hallvard Feb 09 '18 at 15:02
  • @khelwood That's OK, but if you at some point want to understand the rest of it, I recommend trying out http://www.statisticshowto.com/calculators/permutation-calculator-and-combination-calculator/ – Hallvard Feb 10 '18 at 13:20
  • The reason is that you said there were 27 3-character combinations (i.e. order not mattering) of RGB. That is not correct. There are 10, namely the ones I listed. There are 27 3-character permutations (i.e. order mattering). Here is a simple proof: In the list of 27, you will find [r, r, g], [r, g, r] and [g, r, r]. They are three different permutations of one single combination. – Hallvard Feb 10 '18 at 23:42
  • @khelwood You have obviously failed to read my early comment where I agreed with you on that, but disagreed with your erroneous statement about “27 combinations”. – Hallvard Feb 12 '18 at 16:36
  • @khelwood How do you go from "27 permutations, but 10 combinations" to "27 equals 10"? – Hallvard Feb 12 '18 at 16:50

3 Answers3

4

This should work:

from itertools import product

list(product('rgb', repeat=3))
jpp
  • 159,742
  • 34
  • 281
  • 339
1

The problem is that with

comb_list.append(current_combination)

you are appending the same list again and again to the result list. Thus changing a value in that list, e.g. with current_combination[0] = rgb[x] will also change the value in all the "other" lists.

You could fix this by creating a new list from that list prior to insertion:

comb_list.append(list(current_combination))

Or just create that list from the three elements directly when adding it to the result:

for x in rgb:
    for y in rgb:
        for z in rgb:
            comb_list.append([x, y, z])

Or just use a list-comprehension for the whole thing:

comb_list = [[x, y, z] for x in rgb for y in rgb for z in rgb]

Or use itertools.product, as described in the other answer.

tobias_k
  • 81,265
  • 12
  • 120
  • 179
0

One Solution:

import itertools

result = itertools.product("rgb",repeat = 3)    
print(list(result))
Gab
  • 512
  • 4
  • 7