Use range as a dictionary key in Python, what is my option?

This is my first post and I am completely new in programming, so I may not be able to pass my question properly, but I will do my best!

tries_dict = {1:'first', 2:'second', 3:'third', 4:'fourth', ub_tries:'last'} ub_tries = user input tries = 1 input ('\nCome on make your ' + tries_dict.get(tries) + guess: ') 

These 3 elements are part of the game with the number of words I created, and I included them in the while , where tries += 1 after each incorrect answer.

As you can see, my dictionary has custom values ​​for the first 4 answers and the last possible chance before the game ends, so here is what I tried to do:

I wanted to find a way to have a “NEXT” value for each answer / key between the “fourth” and “last”.

How in:

 tries = 5 Come on make your next guess tries = 6 Come on make your next guess 

etc.

I found a way with some complicated loop, but being a curious type, I wanted to know more efficient / practical ways to achieve this.

Here are some options that I thought about but couldn't work:

  • Using a range as a key
  • Finding a way to create a list with values ​​between 4 and ub_tries and use this list as a key

So, generally speaking: how to create a way to get this general answer (next or any other) for keys that are not listed in the dictionary?

Any feedback would be greatly appreciated, feel free to ask for clarification, as I can tell myself that my question is a bit dirty.

Hopefully I get more tricks when programming as well as asking related questions, so far my programming is almost as dirty as my final skills, sigh!

0
source share
4 answers

I'm not sure if this is what you want, but dict.get might 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 can wrap this in a function in various ways. For instance:

 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') 

In any case, dict.get(key, default=None) is similar to dict[key] , except that if key not a member, instead of raising a KeyError , it returns default .

As for your suggestions:

using range as key

Of course you can do this (if you are using Python 2 instead of 3, use xrange for range ), but how does this help?

 d = { range(1, 5): '???', range(5, ub_tries): 'next', range(ub_tries, ub_tries + 1): 'last' } 

This is completely legal, but d[6] is about to raise a KeyError because 6 is not the same as range(5, ub_tries) .

If you want this to work, you can build a RangeDictionary as follows:

 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 this is far beyond Python for Beginners, even for this terribly inefficient, incomplete, and unreliable implementation, so I would not suggest it.

find a way to generate a list with values ​​between 4 and ub_tries and use a list like the key

Do you mean 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' 

This works, but it is probably not a good solution.

Finally, you can use defaultdict , which allows you to bake the default value in the dictionary, rather than passing it as part of every 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 constantly creates each element the first time you request it, and you need to create a function that returns the default value. This makes it more useful for cases where you are going to update the values, and just want the default starting point.

+5
source

I captured your intention to play here?

 max_tries = 8 tries_verbage = { 1: 'first', 2: 'second', 3: 'third', 4: 'fourth', max_tries: 'last' } for i in xrange(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 
+1
source

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)) 

Please note that this code will not work as planned for MAX_TRIES = 0 , but I do not think it will be a problem.

+1
source

You can use a dictionary with a range as a key:

 def switch(x): return { 1<x<4: 'several', 5<x<40: 'lots' }[1] def main(): x = input("enter no. of monsters ") print switch(x) return 0 

Hope this helps. :)

+1
source

Source: https://habr.com/ru/post/1242599/


All Articles