Dictionary with multiple keys mapping to same value

Question:

I have a need to take an integer value and index into a table of corresponding strings. In this case, contiguous ranges of integers should all map to the same string. Something like (with a non-working dictionary example):

int_dict = { 0              : "String1",
             1              : "String2",
             2              : "String3",
             range(3,15)    : "String4",
             16             : "String5"   };

As expected, using range here just fails and trying to use lists gives the error TypeError: unhashable type: 'list'.

Perhaps a dictionary is not the best data structure for this task. My question, then, is how can something like this be easily done? The ranges tend to be quite large, so doing this via manual definition (unless something like range can be used) is not an option.

Asked By: sherrellbc

||

Answers:

Is it what you want to achieve ?

int_dict = { 0              : "String1",
             1              : "String2",
             2              : "String3",
             16             : "String5"   };
#range is first inclusive last exlusif, watch out for that
for i in range(3,15)    :
    int_dict[i] = "String4"

output :

{0: 'String1',
 1: 'String2',
 2: 'String3',
 3: 'String4',
 4: 'String4',
 5: 'String4',
 6: 'String4',
 7: 'String4',
 8: 'String4',
 9: 'String4',
 10: 'String4',
 11: 'String4',
 12: 'String4',
 13: 'String4',
 14: 'String4',
 16: 'String5'}

Edit : you can also use tuple as key

int_dict = { (0,0)              : "String1",
             (1,1)              : "String2",
             (2,2)              : "String3",
              (3,15)             :"String4",
             (16,16)             : "String5"};

def ValueInDict(value):
    for i,j in int_dict.items():
        if value >= i[0]:
            if value <= i[1]:
                print(j)
                return
    print("NOT THERE")

ValueInDict(5)

ouput :

 String4
Answered By: Tbaki

What about nested dictionaries? First level key being left side of the interval and second level key being the right side?

d = {0:{0:"String1"},
...
 3:{15:"String4"},
 16:{16:"String5"}};
Answered By: c-garcia

I don’t think there is a special syntax for that rare case. But you can create a dict with a range of keys and the values you want. And add it to you int_dict using update.

int_dict = {
    0: "String1",
    1: "String2",
    2: "String3",
    16: "String5"
}
int_dict.update({i: "String4" for i in range(3, 16)})
Answered By: Leonid Mednikov

With dict comprehension:

int_dict = {n:'String{}'.format(n+1) for n in range(0,4)}
int_dict.update({n:'String4' for n in range(3,16)})
int_dict.update({16:'String5'})
Answered By: juankysmith

I propose a solution that I find more pythonic: first a dictionary with the keys having different values is created, then it is updated with a dictionary the keys having the same values by using dict.fromkeys

int_dict = {
    0: "String1",
    1: "String2",
    2: "String3",
    16: "String5"
}
int_dict.update(dict.fromkeys(range(3,15), "String4"))
Answered By: Dr Fabio Gori
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.