Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Range as dictionary key in Python

So, I had an idea that I could use a range of numbers as a key for a single value in a dictionary.

I wrote the code bellow, but I cannot get it to work. Is it even possible?

    stealth_roll = randint(1, 20)     # select from a dictionary of 4 responses using one of four ranges.     ## not working.     stealth_check = {                     range(1, 6) : 'You are about as stealthy as thunderstorm.',                     range(6, 11) : 'You tip-toe through the crowd of walkers, while loudly calling them names.',                     range(11, 16) : 'You are quiet, and deliberate, but still you smell.',                     range(16, 20) : 'You move like a ninja, but attracting a handful of walkers was inevitable.'                     }      print stealth_check[stealth_roll] 
like image 420
Cuylar Conly Avatar asked Sep 06 '16 21:09

Cuylar Conly


People also ask

Can a range be a key in dictionary Python?

Yes, you can, only if you convert your range lists as immutable tuple , so they are hashable and accepted as keys of your dictionary: stealth_check = { tuple(range(1, 6)) : 'You are about as stealthy as thunderstorm.

Can a dictionary have a list as a key Python?

A dictionary or a list cannot be a key. Values, on the other hand, can literally be anything and they can be used more than once.

Can I get a key from a dictionary from the value Python?

Method 1 : Using List. Step 1: Convert dictionary keys and values into lists. Step 2: Find the matching index from value list. Step 3: Use the index to find the appropriate key from key list.

How do I convert a list to a dictionary in Python?

Since python dictionary is unordered, the output can be in any order. To convert a list to dictionary, we can use list comprehension and make a key:value pair of consecutive elements. Finally, typecase the list to dict type.


1 Answers

It is possible on Python 3 — and on Python 2 if you use xrange instead of range:

stealth_check = {                 xrange(1, 6) : 'You are about as stealthy as thunderstorm.', #...                 } 

However, the way you're trying to use it it won't work. You could iterate over the keys, like this:

for key in stealth_check:     if stealth_roll in key:         print stealth_check[key]         break 

Performance of this isn't nice (O(n)) but if it's a small dictionary like you showed it's okay. If you actually want to do that, I'd subclass dict to work like that automatically:

class RangeDict(dict):     def __getitem__(self, item):         if not isinstance(item, range): # or xrange in Python 2             for key in self:                 if item in key:                     return self[key]             raise KeyError(item)         else:             return super().__getitem__(item) # or super(RangeDict, self) for Python 2  stealth_check = RangeDict({range(1,6): 'thunderstorm', range(6,11): 'tip-toe'}) stealth_roll = 8 print(stealth_check[stealth_roll]) # prints 'tip-toe' 
like image 67
L3viathan Avatar answered Oct 09 '22 10:10

L3viathan