8

Possible Duplicate:
Python decimal range() step value

I would like generate list like this:

[0, 0.05, 0.1, 0.15 ... ] 

range(0, 1, 0.05) would be great but it doesn't work beacuse:

range() integer step argument expected, got float.

Have you any elegant idea? ;)

2

5 Answers 5

6

If you can use numpy, it's a good idea to use numpy.linspace. Functions that try to fit range logic on floating-point numbers, including numpy's own arange, usually get confusing regarding whether the end boundary ends up in the list or not. linspace elegantly resolves that by having you to explicitly specify the start point, the end point, and the desired number of elements:

>>> import numpy >>> numpy.linspace(0.0, 1.0, 21) array([ 0. , 0.05, 0.1 , 0.15, 0.2 , 0.25, 0.3 , 0.35, 0.4 , 0.45, 0.5 , 0.55, 0.6 , 0.65, 0.7 , 0.75, 0.8 , 0.85, 0.9 , 0.95, 1. ]) 
Sign up to request clarification or add additional context in comments.

4 Comments

You can't win: linspace might get confusing about how many items are there ("why 21 and not 20?"). True that a comment would always be in order anyway.
I was thinking the exact same thing while I was changing 20 to 21 after my initial example failed to work as expected. :) Still, this kind of confusion is much less subtle and prone to surprises than the confusion of whether the end point gets included in the range (and how to always make it there if it's not). It's always a tradeoff, but at least here it's obvious that you get what you asked for — len of the resulting array is 21.
You always get what you ask for. That's the tragedy of programming :)
You can specify if the last point should be included or not. Have a look at the endpoint argument.
6

In Python 3, range returns a generator (immutable sequence)... so I think we can define a very simple function like:

def frange(start,stop, step=1.0): while start < stop: yield start start +=step 

So:

for x in frange(0, 1, 0.05): print(x) 

Python doesn't need to be tricky.

If you want a list, just call:

list(frange(0,1,0.05)) 

Or change the function to return a list right away.

You can use one line solutions that multiply or do other stuff, but it can be tricky with different start and end values. If you use this kind of ranges frequently, just use the function and reuse it. Even a one-liner repeated many times on code is bad.

2 Comments

This is kind of pedantic, but range() returns a list. xrange() returns a generator.
Not in Python 3. range returns a generator (immutable sequence) and xrange does not exist anymore. I will fix the print to make it clear it is python 3.
3

Or how about this:

[v*0.05 for v in range(0,int(1/0.05))] 

4 Comments

You risk to 'shave off' the last element, maybe. I think doing the division in the comprehension is clearer. On the other hand your method allows choosing whether to explicitly use rounding or truncating for range calculation, so it could be better in some cases.
Alternatively you could always do the math yourself [v*0.05 for v in range(0,20)], I just tried to show that one liner is possible :)
Yes, that's why I +1'd your solution. But I'm more comfortable doing the math myself, and possibly explaining in the comment.
@IvanKoblik I am trying to do the same thing but I don't want to generate a list. How would you adapt what you have done for a for loop of the type for C in range()?
1

How about this:

temp = range(0,100,5) # 0,5,10,...,95 final_list = map(lambda x: x/100.0,temp) # becomes 0,0.05,0.10,...,0.95 

It's not very elegant, but I've never bothered into making a proper function. Also, it only works if the step size is rational. The advantage is that it's quick enough to be done on the spot.

See comments to your OP for a more general and more elegant solution.

Comments

1

What's wrong with

[i/100.0 for i in range(0, 100, 5)] 

? You check how many digits you want (here two) and whip out a suitable multiplier (1 becomes 100, 0.05 becomes 5).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.