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:
class RangeDictionary(dict):
def __getitem__(self, key):
for r in self.keys():
if key in r:
return super().__getitem__(r)
return super().__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 in range(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.