Use A Range As A Dictionary Key In Python, What Option Do I Have?
Solution 1:
I'm not sure whether this is what you want, but dict.get
may be the answer:
>>>ub_tries = 20>>>tries_dict = {1:'first', 2:'second', 3:'third', 4:'fourth', ub_tries:'last'}>>>tries_dict.get(1, 'next')
'first'
>>>tries_dict.get(4, 'next')
'fourth'
>>>tries_dict.get(5, 'next')
'next'
>>>tries_dict.get(20, 'next')
'last'
>>>tries_dict.get(21, 'next')
'next'
Of course you could wrap this up in a function, in various different ways. For example:
def name_try(try_number, ub_tries):
tries_dict = {1:'first', 2:'second', 3:'third', 4:'fourth', ub_tries:'last'}
return tries_dict.get(try_number, 'next')
At any rate, dict.get(key, default=None)
is like dict[key]
, except that if key
is not a member, instead of raising a KeyError
, it returns default
.
As for your suggestions:
using a range as a key??
Sure, you can do that (if you're in Python 2 instead of 3, use xrange
for range
), but how would it help?
d = { range(1, 5): '???',
range(5, ub_tries): 'next',
range(ub_tries, ub_tries + 1): 'last' }
That's perfectly legal—but d[6]
is going to raise a KeyError
, because 6
isn't the same thing as range(5, ub_tries)
.
If you want this to work, you could build a RangeDictionary
like this:
classRangeDictionary(dict):def__getitem__(self, key):
for r inself.keys():
if key inr:returnsuper().__getitem__(r)
returnsuper().__getitem__(key)
But that's well beyond "beginners' Python", even for this horribly inefficient, incomplete, and non-robust implementation, so I wouldn't suggest it.
finding a way to generate a list with values between 4 and ub_tries and using such list as a key
You mean like this?
>>> ub_tries = 8>>> tries_dict = {1:'first', 2:'second', 3:'third', 4:'fourth', ub_tries:'last'}
>>> tries_dict.update({i: 'next'for i inrange(5, ub_tries)})
>>> tries_dict
{1: 'first', 2: 'second', 3: 'third', 4: 'fourth', 5: 'next', 6: 'next', 7: 'next', 8: 'last'}
>>> tries_dict[6]
'next'
That works, but it's probably not as good a solution.
Finally, you could use defaultdict
, which lets you bake the default value into the dictionary, instead of passing it as part of each call:
>>> from collections import defaultdict
>>> tries_dict = defaultdict(lambda: 'next',
... {1:'first', 2:'second', 3:'third', 4:'fourth', ub_tries:'last'})
>>> tries_dict
defaultdict(<function <lambda> at 0x10272fef0>, {8: 'last', 1: 'first', 2: 'second', 3: 'third', 4: 'fourth'})
>>> tries_dict[5]
'next'>>> tries_dict
defaultdict(<function <lambda> at 0x10272fef0>, {1: 'first', 2: 'second', 3: 'third', 4: 'fourth', 5: 'next', 8: 'last'})
However, note that this permanently creates each element the first time you ask for it—and you have to create a function that returns the default value. This makes it more useful for cases where you're going to be updating values, and just want a default as a starting point.
Solution 2:
You can use a dictionary with range as a key:
defswitch(x):
return { 1<x<4: 'several', 5<x<40: 'lots'}[1]
x = input("enter no. of monsters ")
print switch(x)
Hope this helps. :)
Solution 3:
Have I captured your intent for the game here?
max_tries = 8
tries_verbage = {
1: 'first',
2: 'second',
3: 'third',
4: 'fourth',
max_tries: 'last'
}
for i inxrange(1, max_tries + 1):
raw_input('Make your %s guess:' % tries_verbage.get(i, 'next'))
returns
Make your first guess:1
Make your second guess:2
Make your third guess:3
Make your fourth guess:4
Make your next guess:5
Make your next guess:6
Make your next guess:7
Make your last guess:8
Solution 4:
Why don't you just use a list?
MAX_TRIES = 10
tries_list = ["first", "second", "third", "fourth"]
for word in (tries_list[:MAX_TRIES-1] +
(["next"] * (MAX_TRIES - len(tries_list) - 1)) + ["last"]):
result = raw_input("Come on, make your {} guess:".format(word))
Note this code won't work as planned for MAX_TRIES = 0
, but I don't think that will be a problem.
Post a Comment for "Use A Range As A Dictionary Key In Python, What Option Do I Have?"