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]
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.
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.
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.
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.
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'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With