randint how float python random

how - Python: ¿por qué `random.randint(a, b)` devuelve un rango que incluye `b`?



random.randint python (4)

Siempre me ha parecido extraño que random.randint(a, b) devuelva un entero en el rango [a, b] , en lugar de [a, b-1] como range(...) .

¿Hay alguna razón para esta aparente inconsistencia?


Esto es especulación, pero el uso humano normal de ''darme un número aleatorio de aa b'' es inclusivo. Implementarlo de esa manera tiene sentido, dada la filosofía general de Python de ser un lenguaje más legible para los humanos.


Intenté llegar al fondo de esto examinando algunas fuentes antiguas. Sospeché que randint se implementó antes del entero largo de Python: lo que significa que si querías un número aleatorio que incluyera INT_MAX , necesitarías llamar a random.randrange(0, INT_MAX + 1) que se habría desbordado y habría resultado en argumentos de (0, 0) o (0, INT_MIN) dependiendo.

Sin embargo, mirando tan atrás como incluso las fuentes de Python 1.5.2 , en Lib/whrandom.py vemos:

# # Get a random integer in the range [a, b] including both end points. # (Deprecated; use randrange below.) # def randint(self, a, b): return self.randrange(a, b+1)

whrandom.randint se siguió desaprobando en 2.0 , 2.1 , 2.2 y 2.3 ; pero random.randint se marcó como obsoleto en 2.1 , aunque ya no se marcó como obsoleto en 2.2 .

Además, 2.1 es el primero en anotar en random.randint ''s docstring:

def randrange(self, start, stop=None, step=1, int=int, default=None): """Choose a random item from range(start, stop[, step]). This fixes the problem with randint() which includes the endpoint; in Python this is usually not what you want. Do not supply the ''int'' and ''default'' arguments. """

La única fuente disponible anterior a eso es la fuente 0.9.1 , y hasta donde puedo decir, randint no se implementó en ese punto.

Por lo tanto, llego a la conclusión de que el razonamiento de randint incluido el punto final, es conocido solo por el propio Guido en este punto; dado el docstring de Python 2.1, parece que la razón pudo haber sido un simple error.


No creo que haya una razón para eso. Pero al menos está documentado.


Supongo que random.randint fue solo el primer intento de implementar esta característica. Parece que los desarrolladores de Python también sintieron que esto era un problema, por lo que en v1.5.2 agregaron otro método de randrange con más parámetros estándar:

random.randrange([start], stop[, step])

Devuelve un elemento seleccionado al azar del rango (inicio, parada, paso). Esto es equivalente a la elección (rango (inicio, parada, paso)), pero en realidad no construye un objeto rango.

Puede usar randrange lugar de randint para evitar sorprender a la gente.

Por otro lado, en muchas situaciones en las que el problema se expresa como ''elegir un número aleatorio entre 1 y 6'', podría ser más natural usar randint(1, 6) lugar de escribir randrange(1, 7) o randrange(min, max + 1) .