¿Hay alguna manera de pasar de 0 a 1 por 0.1?
Pensé que podría hacerlo de la siguiente manera, pero falló:
for i in range(0, 1, 0.1):
print i
En cambio, dice que el argumento paso no puede ser cero, lo cual no esperaba.
python
floating-point
range
Evan Fosmark
fuente
fuente
itertools.takewhile
yitertools.count
. Sindrange
embargo, no es mejor que el rendimiento.seq
herramienta en GNU coreutils le permite a uno hacerloseq 0 0.1 1
sin errores de redondeo!seq
utiliza ellong double
tipo C internamente y está sujeto a errores de redondeo. Por ejemplo, en mi máquina,seq 0 0.1 1
da1
como su última salida (como se esperaba), peroseq 1 0.1 2
da1.9
como la última salida (en lugar de la esperada2
).itertools.takewhile(lambda x: (x+0.05)<1, itertools.count(0,0.1))
oitertools.islice(itertools.count(0,0.1), 10)
(después de que lo haya hechoimport itertools
), aunque no he probado cuál es más eficienteRespuestas:
En lugar de usar un paso decimal directamente, es mucho más seguro expresar esto en términos de cuántos puntos desea. De lo contrario, es probable que un error de redondeo de punto flotante le dé un resultado incorrecto.
Puede usar la función linspace de la biblioteca NumPy (que no es parte de la biblioteca estándar pero es relativamente fácil de obtener).
linspace
toma una cantidad de puntos para regresar y también le permite especificar si se incluye o no el punto final correcto:Si realmente desea utilizar un valor de paso de punto flotante, puede hacerlo con
numpy.arange
.Error de redondeo de punto flotante será causar problemas, sin embargo. Aquí hay un caso simple en el que el error de redondeo
arange
produce una matriz de longitud 4 cuando solo debería producir 3 números:fuente
np.linspace(1.,1.3,4)
ynp.arange(1.,1.3,0.1)
di exactamente la misma salida[start,stop)
(es decir, excluirstop
), por lo que no se esperaría que 1.3 se incluyera en la lista. Vea esta pregunta para saber por qué todavía está incluida y qué hacer contra ella.El rango de Python () solo puede hacer enteros, no coma flotante. En su caso específico, puede utilizar una lista de comprensión en su lugar:
(Reemplace la llamada al rango con esa expresión).
Para el caso más general, es posible que desee escribir una función o generador personalizado.
fuente
(x * 0.1 for x in range(0, 10))
.x/10
lugar dex * 0.1
: D Nada especial en realidad, pero algunos números allí serán más precisos, por ejemplo, para3*0.1
obtener0.30000000000000004
, mientras que para 3/10 obtendrá0.3
:)from __future__ import division; 3/10
devuelve 0.3. Este comportamiento es el predeterminado en Python 3.x.Partiendo de 'xrange ([inicio], stop [, paso])' , puede definir un generador que acepte y produzca cualquier tipo que elija (quédese con los tipos que admiten
+
y<
):fuente
Aumente la magnitud de
i
para el bucle y luego reduzca cuando lo necesite.EDITAR: Sinceramente, no puedo recordar por qué pensé que eso funcionaría sintácticamente
Eso debería tener el resultado deseado.
fuente
for i * 100 in range(0, 100, 10)
: SyntaxError: no se puede asignar al operadorscipy
tiene una función incorporadaarange
que generaliza elrange()
constructor de Python para satisfacer sus requisitos de manejo de flotación.from scipy import arange
fuente
arange
que puedes encontrar en numpy:>>> import scipy >>> import numpy >>> numpy.arange is scipy.arange
volveráTrue
.from nump import arange as range
NumPy es un poco exagerado, creo.
En términos generales, hacer un paso a paso
1/x
paray
ti(
1/x
produjo menos ruido de redondeo cuando lo probé).fuente
Similar a la
seq
función de R , ésta devuelve una secuencia en cualquier orden dado el valor de paso correcto. El último valor es igual al valor de detención.Resultados
fuente
seq(0.5, 3.0)
vuelve[0.5, 1.5, 2.5, 3.5]
. Para evitar que las últimas entradas estén fuera de rango, reemplacen = int(round(...
conn = int(floor(...
con la líneafrom math import floor
en la parte superior (arribadef seq(...
).floor
se usa,seq(0.2, 0.9, 0.1)
no alcanzará el punto final derecho y volverá[0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7, 0.8]
Me temo que la función incorporada range () devuelve una secuencia de valores enteros, por lo que no puede usarla para hacer un paso decimal.
Yo diría que solo use un bucle while:
Si tiene curiosidad, Python está convirtiendo su 0.1 a 0, por lo que le dice que el argumento no puede ser cero.
fuente
.1
10 veces no es lo mismo que agregar1
! docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.htmlAquí hay una solución usando itertools :
Ejemplo de uso:
fuente
en Python 2.7x le da el resultado de:
pero si usas:
te da lo deseado:
fuente
fuente
Y si hace esto a menudo, es posible que desee guardar la lista generada
r
fuente
more_itertools
es una biblioteca de terceros que implementa unanumeric_range
herramienta:Salida
Esta herramienta también funciona para
Decimal
yFraction
.fuente
Mis versiones usan la función de rango original para crear índices multiplicativos para el turno. Esto permite la misma sintaxis a la función de rango original. Hice dos versiones, una con flotador y otra con decimal, porque descubrí que en algunos casos quería evitar la deriva de redondeo introducida por la aritmética de coma flotante.
Es coherente con los resultados del conjunto vacío como en rango / xrango.
Al pasar un solo valor numérico a cualquiera de las funciones, la salida del rango estándar devolverá el valor máximo del número entero del parámetro de entrada (por lo tanto, si le dio 5.5, devolvería el rango (6)).
Editar: el siguiente código ahora está disponible como paquete en pypi: Franges
fuente
frange
funcionar si la parada esNone
? Esa parte del código ya ni siquiera considera el tamaño del paso.range
tiene dos firmas:range(stop)
que asume un valor predeterminadostart=0, step=1
yrange(start, stop, step)
donde no se hacen suposiciones.frange
refleja eso. Cuando se utiliza larange(stop)
firma, tantofrange
ydrange
empezar a 0 y el incremento en un 1, por lo que su comportamiento es idéntico al normalrange(stop)
comportamiento con tope redondeado al número entero más cercano.Esta es mi solución para obtener rangos con pasos flotantes.
Con esta función no es necesario importar numpy ni instalarlo.
Estoy bastante seguro de que podría mejorarse y optimizarse. Siéntase libre de hacerlo y publíquelo aquí.
El resultado es:
fuente
Para completar la boutique, una solución funcional:
fuente
Puedes usar esta función:
fuente
list(frange(99.8, 100.1, 0.1)) => [99.7, 99.80000000000001, 99.9]
El truco para evitar el problema de redondeo es usar un número separado para moverse a través del rango, que comienza y la mitad del paso anterior al inicio .
Alternativamente,
numpy.arange
se puede utilizar.fuente
Se puede hacer usando la biblioteca Numpy. La función arange () permite pasos en flotante. Pero, devuelve una matriz numpy que se puede convertir a la lista usando tolist () para nuestra conveniencia.
fuente
Mi respuesta es similar a otras que usan map (), sin necesidad de NumPy, y sin usar lambda (aunque podría). Para obtener una lista de valores flotantes de 0.0 a t_max en pasos de dt:
fuente
Nadie sorprendido ha mencionado aún la solución recomendada en los documentos de Python 3 :
Una vez definida, la receta es fácil de usar y no requiere
numpy
ni ninguna otra biblioteca externa, pero funciona comonumpy.linspace()
. Tenga en cuenta que, en lugar de unstep
argumento, el tercernum
argumento especifica el número de valores deseados, por ejemplo:Cito una versión modificada de la receta completa de Python 3 de Andrew Barnert a continuación:
fuente
Para contrarrestar los problemas de precisión de flotación, puede usar el
Decimal
módulo .Esto exige un esfuerzo adicional de conversión
Decimal
desdeint
ofloat
mientras se escribe el código, pero en su lugar puede pasarstr
y modificar la función si ese tipo de conveniencia es realmente necesaria.Resultados de muestra:
fuente
Decimal
entradas similares ,np.arange
funciona igual:np.arange(Decimal('-2.0'), Decimal('2.0'), Decimal('0.1'))
Agregue corrección automática para la posibilidad de un inicio de sesión incorrecto en el paso:
fuente
Mi solución:
fuente
La mejor solución: sin error de redondeo
_________________________________________________________________________________
_________________________________________________________________________________
O, para un rango establecido en lugar de puntos de datos establecidos (por ejemplo, función continua), use:
Para implementar una función: reemplace
x / pow(step, -1)
conf( x / pow(step, -1) )
y definaf
.Por ejemplo:
fuente
start y stop son inclusivos en lugar de uno u otro (generalmente se excluye stop) y sin importaciones, y utilizando generadores
fuente
Sé que llego tarde a la fiesta aquí, pero aquí hay una solución trivial de generador que funciona en 3.6:
entonces puede llamarlo como el original
range()
... no hay manejo de errores, pero avíseme si hay un error que pueda detectarse razonablemente, y lo actualizaré. o puedes actualizarlo. Este es StackOverflow.fuente
Aquí está mi solución que funciona bien con float_range (-1, 0, 0.01) y funciona sin errores de representación de coma flotante. No es muy rápido, pero funciona bien:
fuente
Solo soy un principiante, pero tuve el mismo problema al simular algunos cálculos. Así es como intenté resolver esto, que parece estar funcionando con pasos decimales.
También soy bastante vago, así que me resultó difícil escribir mi propia función de rango.
Básicamente lo que hice se me cambió
xrange(0.0, 1.0, 0.01)
axrange(0, 100, 1)
y se utiliza la división por100.0
dentro del bucle. También me preocupaba si habría errores de redondeo. Así que decidí probar, si hay alguno. Ahora escuché que si, por ejemplo,0.01
de un cálculo no es exactamente el flotador0.01
compara, debería devolver False (si estoy equivocado, hágamelo saber).Así que decidí probar si mi solución funcionaría para mi rango ejecutando una prueba corta:
E imprimió True para cada uno.
Ahora, si me estoy equivocando totalmente, hágamelo saber.
fuente
Este único trazador de líneas no saturará su código. El signo del parámetro paso es importante.
fuente