HOWTO · Python
Solucione el TypeError: el objeto 'flotante' no se puede interpretar como un número entero en Python
Este artículo explica cómo corregir este error de Python convirtiendo un número de punto flotante antes de usar `range()` y eligiendo la conversión adecuada para el número de iteraciones deseado.
En esta página
Si aparece TypeError: 'float' object cannot be interpreted as an integer, significa que se está pasando un número de punto flotante donde se requiere un entero. Una causa frecuente es proporcionar un valor decimal a range(). Convierte el valor según el número de iteraciones que necesitas; la conversión elegida cambia la cantidad de iteraciones del bucle.
Por qué range() provoca este TypeError con un número de punto flotante
range() crea una secuencia de enteros, por lo que sus argumentos de inicio, fin y paso deben ser enteros (o valores similares a enteros que implementen el protocolo de índices enteros de Python). No se acepta un número de punto flotante como 3.0, aunque su parte fraccionaria sea cero: sigue siendo un float, no un int. Por ejemplo, range(3.5) genera TypeError: 'float' object cannot be interpreted as an integer.
Python mantiene diferenciados los valores enteros y los de punto flotante: 3 es de tipo int, mientras que 3.5 es de tipo float. Una operación aritmética puede producir un número de punto flotante aunque un bucle posterior necesite una cantidad entera. El error señala esa incompatibilidad al llamar a range(); no significa que Python no pueda almacenar ni calcular con números de punto flotante.
Convierte un número de punto flotante en entero antes de usar range()
Convierte la cantidad antes de pasarla a range() y elige la conversión según lo que represente esa cantidad. La función integrada int() se puede usar sin importar ningún módulo. Descarta la parte fraccionaria hacia cero: int(3.7) da 3 y int(-3.7) da -3. No redondea al entero más cercano. Si el valor representa una cantidad medida o un límite calculado, determina si truncarlo produce el número de iteraciones deseado.
Las funciones math.floor() y math.ceil() están disponibles en el módulo math de la biblioteca estándar de Python, así que no hace falta instalar ningún paquete; basta con usar import math. math.floor() devuelve el mayor entero menor o igual que el valor de entrada, mientras que math.ceil() devuelve el menor entero mayor o igual que ese valor. Para 3.7, floor es 3 y ceil es 4; para -3.7, floor es -4 y ceil es -3. Esta diferencia importa cuando el número convertido determina las iteraciones de un bucle: redondear hacia abajo un valor negativo lo aleja más de cero, mientras que int() lo acerca a cero.
Antes de cambiar un valor, identifica qué cuenta, qué significa una unidad parcial y si el límite debe incluir esa última unidad parcial. Un límite de reintentos, una cantidad de páginas o un número de registros pueden requerir reglas distintas. Conserva la medición original para que la conversión no oculte una precisión que puedas necesitar después. El breve programa siguiente aplica una cantidad entera elegida a una secuencia común.
Ejecuta este ejemplo. Las etiquetas que imprime, int: y ceil:, se mantienen en inglés en el código.
import math
count = 3.7
truncated = int(count)
rounded_up = math.ceil(count)
print("int:", truncated)
print("ceil:", rounded_up)
for index in range(truncated):
print(index)
La salida muestra las etiquetas int: y ceil: en inglés: int: 3 y ceil: 4. A continuación aparecen los valores del bucle: 0, 1 y 2.
int: 3
ceil: 4
0
1
2
Elige int(), math.floor() o math.ceil() según el resultado que necesites
Usa int() cuando la regla deseada sea eliminar la parte fraccionaria hacia cero. Usa math.floor() cuando la cantidad no deba superar el valor original, y math.ceil() cuando deba ser como mínimo igual a ese valor. Para entradas positivas, int() y math.floor() dan el mismo resultado; para números negativos no enteros, difieren. Ninguna opción es correcta en todos los casos: considera si el número de punto flotante representa una duración, una cantidad que procesar o un límite, y elige la regla que produzca la cantidad deseada.
Las tres conversiones producen un entero a partir de un número de punto flotante finito, por lo que el resultado sirve para range(). También descartan la información fraccionaria, así que conserva por separado el número de punto flotante original si lo necesitas para cálculos posteriores. Si el valor debería ser una cantidad entera desde el principio, quizá convenga corregir su origen o validarlo antes de convertirlo, en lugar de cambiar la cantidad sin avisar.
Comprueba el valor convertido y el resultado del bucle
Revisa tanto la cantidad convertida como los valores del bucle. range(n) empieza en 0, avanza de 1 en 1 y se detiene antes de llegar a n; por tanto, una cantidad de 3 produce 0, 1 y 2, es decir, tres iteraciones. Una cantidad de 0 no produce iteraciones. Con el paso positivo predeterminado, un límite negativo tampoco produce valores. Estos comportamientos pueden revelar que una conversión cambió el trabajo que realiza tu programa.
En el ejemplo, la salida muestra int: 3 y ceil: 4; las etiquetas int: y ceil: permanecen en inglés. Los valores del bucle que aparecen después son 0, 1 y 2, lo que permite ver el efecto de truncar 3.7. Para comprobar otra entrada, cambia count y compara la conversión con la regla que necesitas. Si la entrada es negativa, compara int(count), math.floor(count) y math.ceil(count) antes de usar uno como límite. La solución adecuada es la conversión cuyo resultado coincide con la cantidad de iteraciones deseada, no simplemente cualquier conversión que haga desaparecer el TypeError.