2

I want to create a dictionary mapping all combinations of three groups to an integer. Is it possible to do this in a single line and without using any imports?

With itertools it could be done with:

colours = ['red','green','blue']
shapes = ['circle','square','triangle']
sizes = ['small','medium','large']
import itertools as it
lookup = {key:val for val,key in enumerate(it.product(colours,shapes,sizes))}

However, I can't figure out how to do enumeration with a nested for-loop and list comprehension. Eg, the below syntax is an attempt, but doesn't increment for each level of the for loop:

lookup = {(c,s,z):i for i,c in enumerate(colours) for s in shapes for z in sizes}

The output should look like:

{('red', 'circle', 'small'): 0,
 ('red', 'circle', 'medium'): 1,
 ('red', 'circle', 'large'): 2,
 ('red', 'square', 'small'): 3,
 ('red', 'square', 'medium'): 4,
...
2
  • 1
    Can you give an example of what the output should look like? Commented Dec 9, 2019 at 22:21
  • 1
    @damon - I've added example output. (You can get the full output by just running the itertools code I gave) Commented Dec 9, 2019 at 22:27

2 Answers 2

4

You could enumerate the inner iterator like so:

>>> {x: i for i, x in enumerate(((c, s, z) for c in colours for s in shapes for z in sizes))}
{('red', 'circle', 'small'): 0,
 ('red', 'circle', 'medium'): 1,
 ('red', 'circle', 'large'): 2,
 ('red', 'square', 'small'): 3,
 ('red', 'square', 'medium'): 4,
 ('red', 'square', 'large'): 5,
 ('red', 'triangle', 'small'): 6,
 ('red', 'triangle', 'medium'): 7,
 ('red', 'triangle', 'large'): 8,
 ('green', 'circle', 'small'): 9,
 ('green', 'circle', 'medium'): 10,
 ('green', 'circle', 'large'): 11,
 ('green', 'square', 'small'): 12,
 ('green', 'square', 'medium'): 13,
 ('green', 'square', 'large'): 14,
 ('green', 'triangle', 'small'): 15,
 ('green', 'triangle', 'medium'): 16,
 ('green', 'triangle', 'large'): 17,
 ('blue', 'circle', 'small'): 18,
 ('blue', 'circle', 'medium'): 19,
 ('blue', 'circle', 'large'): 20,
 ('blue', 'square', 'small'): 21,
 ('blue', 'square', 'medium'): 22,
 ('blue', 'square', 'large'): 23,
 ('blue', 'triangle', 'small'): 24,
 ('blue', 'triangle', 'medium'): 25,
 ('blue', 'triangle', 'large'): 26}

To make the code slightly more readable:

{
    obj: index for index, obj in enumerate(
        (
            (color, shape, size) for color in colours
                                 for shape in shapes
                                 for size in sizes
        )
    )
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. Nice and simple
1

You can try:

lookup = {(c,s,z): i+3*j+9*k for i,c in enumerate(colours) for j,s in enumerate(shapes) for k,z in enumerate(sizes)}

Output:

{
('red', 'circle', 'small'): 0, 
('red', 'circle', 'medium'): 9, 
('red', 'circle', 'large'): 18, 
('red', 'square', 'small'): 3, 
('red', 'square', 'medium'): 12, 
('red', 'square', 'large'): 21, 
('red', 'triangle', 'small'): 6, 
('red', 'triangle', 'medium'): 15, 
('red', 'triangle', 'large'): 24, 
('green', 'circle', 'small'): 1, 
('green', 'circle', 'medium'): 10, 
('green', 'circle', 'large'): 19, 
('green', 'square', 'small'): 4, 
('green', 'square', 'medium'): 13, 
('green', 'square', 'large'): 22, 
('green', 'triangle', 'small'): 7, 
('green', 'triangle', 'medium'): 16, 
('green', 'triangle', 'large'): 25, 
('blue', 'circle', 'small'): 2, 
('blue', 'circle', 'medium'): 11, 
('blue', 'circle', 'large'): 20, 
('blue', 'square', 'small'): 5, 
('blue', 'square', 'medium'): 14, 
('blue', 'square', 'large'): 23, 
('blue', 'triangle', 'small'): 8, 
('blue', 'triangle', 'medium'): 17, 
('blue', 'triangle', 'large'): 26
}

And then in order to sort dict by value:

lookup=dict(sorted(lookup.items(), key=lambda x: x[1] ))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.