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 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
when you reference a specific element in a list you specify his position, by index. positive index value means that count should start from left to right, negative number means that count should start from right to left.
a = [0.1, 1.1, 2.1, 3.1, 4.1]
b = a[-4]
print(b)
# this will print 1.1
so you refer to one element but not to a range of elements in original list.
To get a slice of a you should use something like this
a = [0.1, 1.1, 2.1, 3.1, 4.1]
b = a[-4:]
print(b)
# this will print [1.1, 2.1, 3.1, 4.1]
so, to refer a range of elements you should indicate that range and it can be done in this way list[start_index:end_index] (note semicolons)
Iterate through a list of integers, strings or a list of floats isn't something diferent. They are all handled in the same way, you just have a syntax error, that is. check for line with the explanation in mind.
UPDATE:
you can use min function to get minimum value from a list of elements without iterating through elements. it would be something like this min_value = min(list[-4:])
Right now, your code only fetches the fourth last item from the list.
If you want to fetch the last four elements from the array to iterate over, you need to change the code a hair:
for i in list[-4:]:
print i