Reputation: 235
I am trying to loop between 0.01 and 10, but between 0.01 and 0.1 use 0.01 as the step, then between 0.1 and 1.0 use 0.1 as step, and between 1.0 and 10.0 use 1.0 as step.
I have the while loop code written, but want to make it more pythonic.
i = 0.01
while i < 10:
# do something
print i
if i < 0.1:
i += 0.01
elif i < 1.0:
i += 0.1
else:
i += 1
This will produce
0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1, 2, 3, 4, 5, 6, 7, 8, 9
Upvotes: 21
Views: 6464
Reputation: 665527
I'd recommend a generator function as well, but if the steps are not such convenient powers of each other I'd write it like
def my_range():
i = 0
while i < 0.1:
i += 0.01
yield i
while i < 1:
i += 0.1
yield i
while i < 10:
i += 1
yield i
for x in my_range():
print x
It might be a bit more repetitive, but illustrates much better what is going on and that the yielded values are monotonically increasing (regardless what numbers you put in).
If it gets too repetitive, use
def my_range():
i = 0
for (end, step) in [(0.1, 0.01), (1, 0.1), (10, 1)]:
while i < end:
i += step
yield i
Upvotes: 2
Reputation: 13743
Just in case you wished to replace the loop with vectorized code...
In [63]: np.ravel(10.**np.arange(-2, 1)[:,None] * np.arange(1, 10)[None,:])
Out[64]:
array([ 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09,
0.1 , 0.2 , 0.3 , 0.4 , 0.5 , 0.6 , 0.7 , 0.8 , 0.9 ,
1. , 2. , 3. , 4. , 5. , 6. , 7. , 8. , 9. ])
Upvotes: 2
Reputation: 5870
Just a single line of code through list comprehension -
for k in [i*j for j in (0.01, 0.1, 1) for i in range(1, 10)]
Can't be more pythonic!
Upvotes: 3
Reputation: 21474
You could have a nested loop, the outer one that iterates over the precision and inner one that is just range(1,10)
:
for precision in (0.01, 0.1, 1):
for i in range(1,10):
i*=precision
print(i)
However floats are probably not going to work in this case as this shows values like 0.30000000000000004
on my machine, for precise decimal values you would want to use the decimal
module:
import decimal
for precision in ("0.01", "0.1", "1"):
for i in range(1,10):
i*=decimal.Decimal(precision)
print(i)
Upvotes: 3
Reputation: 12948
You could do something like:
import numpy as np
list1 = np.arange(0.01, 0.1, 0.01)
list2 = np.arange(0.1, 1, 0.1)
list3 = np.arange(1, 10, 1)
i_list = np.concatenate((list1, list2, list3)) # note the double parenthesis
for i in i_list:
...
Basically you create the entire list of values that you need up front, i_list
, then just iterate through them in your for
loop.
Upvotes: 1
Reputation: 168876
A special-purse generator function might be the right way to go. This would effectively separate the boring part (getting the list of numbers right) from the interesting part (the # do something
in your example).
def my_range():
for j in .01, .1, 1.:
for i in range(1, 10, 1):
yield i * j
for x in my_range():
print x
Upvotes: 21
Reputation: 5308
One approach would be to use two loops: one for the order of magnitude, and one for the values from 1 to 9:
for exp in range(-2, 1):
for i in range(1, 10):
print("{:.2f}".format(i * 10 ** exp))
Upvotes: 3