usar un rango como clave de diccionario en Python, ¿qué opción tengo?

Este es mi primer post y soy bastante nuevo en progtwigción, así que es posible que no pueda transmitir mi pregunta de manera adecuada, pero haré lo mejor que pueda.

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

Estos 3 elementos son parte de un juego de adivinanzas numéricas que creé, y los incluí en un bucle while donde tries += 1 después de cada respuesta incorrecta.

Como puedes ver, en mi diccionario hay valores personalizados para las primeras 4 respuestas y la última oportunidad posible antes de que termine el juego, así que esto es lo que intenté hacer:

Quería encontrar una manera de tener el valor ‘SIGUIENTE’ para cada respuesta / clave entre ‘cuarto’ y ‘último’.

Como en:

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

y así

Encontré una manera con algunos bucles complejos, pero siendo el tipo curioso que quería conocer de formas más eficientes / prácticas para lograr esto.

Aquí hay algunas opciones que pensé pero no pude trabajar:

  1. Usando un rango como clave
  2. Encontrar una forma de generar una lista con valores entre 4 y ub_tries y usar esa lista como clave

En términos generales, ¿cómo se puede crear una forma de tener esta respuesta general (siguiente o lo que sea) para las claves que no están especificadas en un diccionario?

Cualquier comentario será muy apreciado, siéntase libre de pedir aclaraciones ya que puedo decirme que mi pregunta es un poco complicada.

Espero obtener más habilidad tanto para progtwigr como para hacer preguntas relacionadas, hasta ahora mi progtwigción es casi tan desordenada como mis habilidades de resumen, ¡suspiro!

No estoy seguro de si esto es lo que quieres, pero dict.get puede ser la respuesta:

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

Por supuesto, podrías envolver esto en una función, de varias maneras diferentes. Por ejemplo:

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

En cualquier caso, dict.get(key, default=None) es como dict[key] , excepto que si key no es un miembro, en lugar de generar un KeyError , devuelve el default .

En cuanto a tus sugerencias:

¿Usando un rango como clave?

Claro, puedes hacer eso (si estás en Python 2 en lugar de 3, usa xrange para el range ), pero ¿cómo te ayudaría?

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

Eso es perfectamente legal, pero d[6] va a generar un KeyError , porque 6 no es lo mismo que range(5, ub_tries) .

Si quieres que esto funcione, podrías construir un RangeDictionary como este:

 class RangeDictionary(dict): def __getitem__(self, key): for r in self.keys(): if key in r: return super().__getitem__(r) return super().__getitem__(key) 

Pero eso va mucho más allá del “Python para principiantes”, incluso para esta implementación horriblemente ineficiente, incompleta y no robusta, por lo que no lo sugeriría.

encontrar una manera de generar una lista con valores entre 4 y ub_tries y usar dicha lista como clave

¿Quieres decir así?

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

Eso funciona, pero probablemente no sea una buena solución.

Finalmente, podría usar defaultdict , que le permite hornear el valor predeterminado en el diccionario, en lugar de pasarlo como parte de cada llamada:

 >>> from collections import defaultdict >>> tries_dict = defaultdict(lambda: 'next', ... {1:'first', 2:'second', 3:'third', 4:'fourth', ub_tries:'last'}) >>> tries_dict defaultdict( at 0x10272fef0>, {8: 'last', 1: 'first', 2: 'second', 3: 'third', 4: 'fourth'}) >>> tries_dict[5] 'next' >>> tries_dict defaultdict( at 0x10272fef0>, {1: 'first', 2: 'second', 3: 'third', 4: 'fourth', 5: 'next', 8: 'last'}) 

Sin embargo, tenga en cuenta que esto crea de forma permanente cada elemento la primera vez que lo solicita, y que tiene que crear una función que devuelva el valor predeterminado. Esto lo hace más útil para los casos en los que va a actualizar los valores, y solo desea un valor predeterminado como punto de partida.

¿He capturado su intención para el juego aquí?

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

devoluciones

 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 

¿Por qué no usas una lista?

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

Tenga en cuenta que este código no funcionará como se planeó para MAX_TRIES = 0 , pero no creo que sea un problema.

Puedes usar un diccionario con rango como clave:

 def switch(x): return { 1 

Espero que esto ayude. 🙂