You can't use the built in to do float/decimal increments but it is fairly easy to construct your own generator:
def decimal_range(start, stop, increment):
while start < stop: # and not math.isclose(start, stop): Py>3.5
yield start
start += increment
for i in decimal_range(Rangelow, Rangehigh, Delta):
...
Or you could use numpy but this feels like a sledgehammer cracking a nut:
import numpy as np
for i in np.arange(Rangelow, Rangehigh, Delta):
...
Answer from AChampion on Stack OverflowYou can't use the built in to do float/decimal increments but it is fairly easy to construct your own generator:
def decimal_range(start, stop, increment):
while start < stop: # and not math.isclose(start, stop): Py>3.5
yield start
start += increment
for i in decimal_range(Rangelow, Rangehigh, Delta):
...
Or you could use numpy but this feels like a sledgehammer cracking a nut:
import numpy as np
for i in np.arange(Rangelow, Rangehigh, Delta):
...
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import decimal
def range_decimal(start, stop, step, stop_inclusive=False):
""" The Python range() function, using decimals. A decimal loop_value generator.
Note: The decimal math (addition) defines the rounding.
If the stop is None, then:
stop = start
start = 0 (zero)
If the step is 0 (zero) or None, then:
if (stop < start) then step = -1 (minus one)
if (stop >= start) then step = 1 (one)
Example:
for index in range_decimal(0, 1.0, '.1', stop_inclusive=True):
print(index)
:param start: The loop start value
:param stop: The loop stop value
:param step: The loop step value
:param stop_inclusive: Include the stop value in the loop's yield generator: False = excluded ; True = included
:return: The loop generator's yield increment value (decimal)
"""
try:
# Input argument(s) error check
zero = decimal.Decimal('0')
if start is None:
start = zero
if not isinstance(start, decimal.Decimal):
start = decimal.Decimal(f'{start}')
if stop is None:
stop = start
start = zero
if not isinstance(stop, decimal.Decimal):
stop = decimal.Decimal(f'{stop}')
if step is None:
step = decimal.Decimal('-1' if stop < start else '1')
if not isinstance(step, decimal.Decimal):
step = decimal.Decimal(f'{step}')
if step == zero:
step = decimal.Decimal('-1' if stop < start else '1')
# Check for valid loop conditions
if start == stop or (start < stop and step < zero) or (start > stop and step > zero):
return # Not valid: no loop
# Case: increment step ( > 0 )
if step > zero:
while start < stop: # Yield the decimal loop points (stop value excluded)
yield start
start += step
# Case: decrement step ( < 0 )
else:
while start > stop: # Yield the decimal loop points (stop value excluded)
yield start
start += step
# Yield the stop value (inclusive)
if stop_inclusive:
yield stop
except (ValueError, decimal.DecimalException) as ex:
raise ValueError(f'{__name__}.range_decimal() error: {ex}')
This is a Python range() equivalent function, using decimals.
The yielded values are exact.
Rangelow = 36
Rangehigh = 37
Delta = 0.1
print("Celsius to Fahrenheit by", Delta)
for i in range_decimal(Rangelow, Rangehigh, Delta, stop_inclusive=True):
print(f'{i:.1f} {i * 9 / 5 + 32}')
Celsius to Fahrenheit by 0.1
36.0 96.8
36.1 96.98
36.2 97.16
36.3 97.34
36.4 97.52
36.5 97.7
36.6 97.88
36.7 98.06
36.8 98.24
36.9 98.42
37.0 98.6
Hi! I want to make a loop that supports float with steps. Normally a step loop would look like this:
for x in range(0, 50, 2):
print(x)
Where the loop goes from 0 to 50 in steps of two and return 25 numbers. However, if I want the value, x to increase by 0.1, I need to make a loop that looks like this:
while x < 50:
print(x)
x += 0.1
This will return 500 values of the variable, x. This seems to work fine, but here's my problem. It might seem like a stupid approach because I use a dumb example. But I do this for simplicity and to give and get an overview.
var = 60
stop = var/2
x = -stop
step = var/3
while x < stop:
print(x)
x += step
In this example I will return -30.0, -10.0 and 10.0. I want it to return -30, 0, and 30, so it reaches the lowest value, middle and highest value. I can do that by simply chaning the step variable to 30, but I want the code to be dynamic, so it will work with every (positive) value in the variable, step.
I hope this made sense. If not, please let me know. I have been struggling with this for quite some time now and I can't figure it out.
Thanks :-)
You can use math module in python to separate decimal and integer part
import math
x = 1001.0010101
math.modf(x)
#output:(0.0010101000000304339, 1001.0)
Iterate as you want
Have doubt about extra numbers in end of decimal read docs
x = 1001.0010101
x = "{0:.5f}".format(x)
for i in str(x).split(".")[1]:
print(i)
Output:
0
0
1
0
1
You can define your own "xrange" for floats using yield. Because there is not built-in function to do that.
>>> def frange(start, stop, step):
... x = start
... while x < stop:
... yield x
... x += step
Then in you can do
>>>for x in frange(5.5,0,0.1):
... print x
range expects integer arguments. But you can do this with:
for x in xrange(55,0,-1):
print x*1.0/10
You could use numpy.arange.
EDIT: The docs prefer numpy.linspace. Thanks @Droogans for noticing =)
One explanation might be floating point rounding issues. For example, if you could call
range(0, 0.4, 0.1)
you might expect an output of
[0, 0.1, 0.2, 0.3]
but you in fact get something like
[0, 0.1, 0.2000000001, 0.3000000001]
due to rounding issues. And since range is often used to generate indices of some sort, it's integers only.
Still, if you want a range generator for floats, you can just roll your own.
def xfrange(start, stop, step):
i = 0
while start + i * step < stop:
yield start + i * step
i += 1
The range function does not handle floats
I am trying to convert something from PHP to Python, but came across a problem since the range function can only step by integers.
I will divide a circle into 16 parts. In PHP I have written:
for ($degrees = 0; $degrees < 360; $degrees += 22.5) {
...I was going to write it like this in Python:
for degrees in range(0, 360, 22.5):
...What is the easiest / nicest way to achieve this?
From what I see, inner1test is a tuple of lists, so the i value will not be an index but the actual list.
You should use enumerate, which returns two variables, the index and the actual data.
for i, value in enumerate(inner1test):
for j, number in enumerate(inner1train):
dist = np.linalg.norm(inner1test[i][0:4]-inner1train[number][0:4])
print(dist)
Also, if your lists begin the be bigger, consider using a generator which will execute your calculcations iteration per iteration and return only one value at a time, avoiding to return a big chunk of results which would occupy a lot of memory.
eg:
def my_calculatiuon(inner1test, inner1train):
for i, value in enumerate(inner1test):
for j, number in enumerate(inner1train):
dist = np.linalg.norm(inner1test[i][0:4]-inner1train[number][0:4])
yield dist
for i in my_calculatiuon(inner1test, inner1train):
print(i)
You might also want to investigate python list comprehension which is sometimes more elegant way to handle for loops with lists.
[EDIT]
Here's a probably easier solution anyway, without the need of indexes, which won't fail to enumerate a numpy object:
for testvalue in inner1test:
for testtrain in inner1train:
dist = np.linalg.norm(testvalue[0:4]-testtrain[0:4])
[/EDIT]
This was the final solution with the correct output for me:
distanceslist = list()
for testvalue in inner1test:
for testtrain in inner1train:
dist = np.linalg.norm(testvalue[0:4]-testtrain[0:4])
distances = (dist, testtrain[0:4])
distanceslist.append(distances)
distanceslist