Assign a unique integer to all combinations of ordered non-repeated elements

Consider the following list:

elems = ('banana', 'apple', 'orange', 'melon')

I need to define a function that assigns a unique integer to each ordered combination of one to three non-repeated elements. For example:

banana                --> 1
banana, apple         --> 2
banana, orange        --> 3
banana, melon         --> 4
banana, apple, orange --> 5
banana, apple, melon  --> 6
banana, orange, apple --> 7
banana, orange, melon --> 8
banana, melon, apple  --> 9
banana, melon, orange --> 10
apple                 --> 11
apple, banana         --> 12
apple, orange         --> 13

My actual list contains more than 20 elements so defining the entire set of combinations manually is not possible. The function would take as input a minimum of one and a maximum of three elements, and return the unique integer associated with them, following the above convention.

I’ve been playing around with itertools.combinations() and itertools.combinations_with_replacement() but they don’t return what I need.


Well, given the powerset of the elements, e.g. from the answers to this question:

How to get all subsets of a set? (powerset)

It seems like what you want is all the permutations of the elements of the powerset, right?

list(enumerate([p for s in powerset(elems) for p in permutations(s)]))
# => [(0, ()), (1, ('banana',)), (2, ('apple',)), (3, ('orange',)), 
(4, ('melon',)), (5, ('banana', 'apple')), (6, ('apple', 'banana')), 
(7, ('banana', 'orange')), (8, ('orange', 'banana')), 
(9, ('banana', 'melon')), (10, ('melon', 'banana')),
(11, ('apple', 'orange')), (12, ('orange', 'apple')), 
(13, ('apple', 'melon')), (14, ('melon', 'apple')), 
(15, ('orange', 'melon')), (16, ('melon', 'orange')), 
(17, ('banana', 'apple', 'orange')), [...] 
(64, ('melon', 'orange', 'apple', 'banana'))]

You can run it through sorted before enumerating to get them in a different order; with no custom key or comparison func it will order the sequences such that all the ones starting with apple come first, then all the ones starting with banana, and so on..)