¿Cómo reemplazar muchas declaraciones ‘if … elif’ en Python?

Escribí un código con muchas declaraciones ‘if..elif’ en Python. Sé que el estilo del código puede considerarse malo y quiero mejorarlo.

num = int(input('please input a number: ')) if num <= 0: print('1') elif 0 < num <= 5: print('2') elif 5 < num <= 10: print('3') elif 10 < num <= 15: print('4') elif 15 < num <= 20: print('5') elif 20 < num <= 25: print('6') 

Me gustaría saber cómo reemplazar tantas declaraciones ‘if..elif’ con otras soluciones?

Podrías hacer algo como esto:

 print(((num - 1) // 5) + 2) 

Ejemplo cuando num es 20:

 ((num - 1) // 5) + 2 ((20 - 1) // 5) + 2 (19 // 5) + 2 3 + 2 5 

En el caso general … no estoy seguro. Si está hablando de una construcción completamente arbitraria if-elif-else, entonces diría que no, al menos no de una manera que ayude a la legibilidad. De hecho, la respuesta que acabo de darte para tu ejemplo específico quizás ni siquiera ayude a la legibilidad, así que no estoy seguro de qué tan bien puedes esperar eso en el caso general.

Podría acortar un poco el código eliminando uno de los dos < controles de cada condicional, como así

 num=int(input('please input a number: ')) if num<=0: print('1') elif num<=5: print('2') elif num<=10: print('3') 

Para ejemplos simples como este, donde los diferentes casos se ajustan a un patrón claro, lo mejor sería algo como lo que sugirió RedRoboHood en donde elimina el condicional por completo (modificado ligeramente para admitir el límite inferior), por ejemplo

 print('%s' % max((num - 1) // 5 + 2, 1)) 

Si desea ser un poco más general y permitir declaraciones de impresión que no sigan un patrón con la entrada, podría usar un diccionario de python:

 # what to print if num is less than the number but greater than the previous mapping = {0:'1', 5:'2', 10:'3', 15:'4', 20:'5', 25:'6'} # clamp the number to the upper bound of the desired range clamped_num = 5 * max((num - 1) // 5, -1) + 5 print(mapping[clamped_num] if clamped_num in mapping else 'Bad value') 

Sin embargo, siempre habrá momentos en los que no se pueda resumir de esta manera, y para ellos creo que las afirmaciones if-else están bien.

 num = int(input('please input a number: ')) if num < 26: print(1 + len([i for i in [0, 5, 10, 15, 20, 25] if i < num])) 

La biblioteca bisect también podría usarse en esta situación y también sería bastante eficiente. La documentación da un ejemplo de uso para los límites de grado de examen. Este enfoque lo haría más flexible si se usaran límites no lineales.

 import bisect def boundaries(num, breakpoints=[0, 5, 10, 15, 20, 25], result='1234567'): i = bisect.bisect(breakpoints, num-1) return result[i] num = int(input('please input a number: ')) print(boundaries(num)) 

Note que esto solo fue probado en Python 2.7.

Esta es otra manera de hacerlo:

 a = { '1': (range(1,6)), '2': (range(6,11)), '3': (range(11,16)), '4':(range(16,21)), '5':(range(21,26))} num=int(input('please input a number: ')) b = {k:v for k,v in a.items() if num in v} c = b.keys() print c[0] 

en print(c[0]) Python3 print(c[0])