Python2.x:

for idx in range(0, int(100 / 0.5)):

    print 0.5 * idx      

outputs:

0.0

0.5

1.0

1.5

..

99.0

99.5


Numpy:

numpy.arange would also do the trick.

numpy.arange(0, 100, 0.5)
Answer from NPE on Stack Overflow
Top answer
1 of 5
88

The range objects are special:

Python will compare range objects as Sequences. What that essentially means is that the comparison doesn't evaluate how they represent a given sequence but rather what they represent.

The fact that the start, stop and step parameters are completely different plays no difference here because they all represent an empty list when expanded:

For example, the first range object:

list(range(0))  # []

and the second range object:

list(range(2, 2, 2)) # []

Both represent an empty list and since two empty lists compare equal (True) so will the range objects that represent them.

As a result, you can have completely different looking range objects; if they represent the same sequence they will compare equal:

range(1, 5, 100) == range(1, 30, 100) 

Both represent a list with a single element [1] so these two will also compare equal.


No, range objects are really special:

Do note, though, that even though the comparison doesn't evaluate how they represent a sequence the result of comparing can be achieved using solely the values of start, step along with the len of the range objects; this has very interesting implications with the speed of comparisons:

r0 = range(1, 1000000)    
r1 = range(1, 1000000)

l0 = list(r0)    
l1 = list(r1)

Ranges compares super fast:

%timeit r0 == r1
The slowest run took 28.82 times longer than the fastest. This could mean that an intermediate result is being cached 
10000000 loops, best of 3: 160 ns per loop

on the other hand, the lists..

%timeit l0 == l1
10 loops, best of 3: 27.8 ms per loop

Yeah..


As @SuperBiasedMan noted, this only applies to the range objects in Python 3. Python 2 range() is a plain ol' function that returns a list while the 2.x xrange object doesn't have the comparing capabilies (and not only these..) that range objects have in Python 3.

Look at @ajcr's answer for quotes directly from the source code on Python 3 range objects. It's documented in there what the comparison between two different ranges actually entails: Simple quick operations. The range_equals function is utilized in the range_richcompare function for EQ and NE cases and assigned to the tp_richcompare slot for PyRange_Type types.

I believe the implementation of range_equals is pretty readable (because it is nice as simple) to add here:

/* r0 and r1 are pointers to rangeobjects */

/* Check if pointers point to same object, example:    
       >>> r1 = r2 = range(0, 10)
       >>> r1 == r2
   obviously returns True. */
if (r0 == r1)
    return 1;

/* Compare the length of the ranges, if they are equal 
   the checks continue. If they are not, False is returned. */
cmp_result = PyObject_RichCompareBool(r0->length, r1->length, Py_EQ);
/* Return False or error to the caller
       >>> range(0, 10) == range(0, 10, 2)  
   fails here */
if (cmp_result != 1)
    return cmp_result;

/* See if the range has a lenght (non-empty). If the length is 0
   then due to to previous check, the length of the other range is 
   equal to 0. They are equal. */
cmp_result = PyObject_Not(r0->length);
/* Return True or error to the caller. 
       >>> range(0) == range(2, 2, 2)  # True
   (True) gets caught here. Lengths are both zero. */
if (cmp_result != 0)
    return cmp_result;

/* Compare the start values for the ranges, if they don't match
   then we're not dealing with equal ranges. */
cmp_result = PyObject_RichCompareBool(r0->start, r1->start, Py_EQ);
/* Return False or error to the caller. 
   lens are equal, this checks their starting values
       >>> range(0, 10) == range(10, 20)  # False
   Lengths are equal and non-zero, steps don't match.*/
if (cmp_result != 1)
    return cmp_result;

/* Check if the length is equal to 1. 
   If start is the same and length is 1, they represent the same sequence:
       >>> range(0, 10, 10) == range(0, 20, 20)  # True */
one = PyLong_FromLong(1);
if (!one)
    return -1;
cmp_result = PyObject_RichCompareBool(r0->length, one, Py_EQ);
Py_DECREF(one);
/* Return True or error to the caller. */
if (cmp_result != 0)
    return cmp_result;

/* Finally, just compare their steps */
return PyObject_RichCompareBool(r0->step, r1->step, Py_EQ);

I've also scattered some of my own comments here; look at @ajcr's answer for the Python equivalent.

2 of 5
17

Direct quote from the docs (emphasis mine):

Testing range objects for equality with == and != compares them as sequences. That is, two range objects are considered equal if they represent the same sequence of values. (Note that two range objects that compare equal might have different start, stop and step attributes, for example range(0) == range(2, 1, 3) or range(0, 3, 2) == range(0, 4, 2).)

If you compare ranges with the "same" list, you'll get inequality, as stated in the docs as well:

Objects of different types, except different numeric types, never compare equal.

Example:

>>> type(range(1))
<class 'range'>
>>> type([0])
<class 'list'>
>>> [0] == range(1)
False
>>> [0] == list(range(1))
True

Note that this explicitly only applies to Python 3. In Python 2, where range just returns a list, range(1) == [0] evaluates as True.

Top answer
1 of 6
52

In Python 3.x ,

range(0,3) returns a class of immutable iterable objects that lets you iterate over them, it does not produce lists, and they do not store all the elements in the range in memory, instead they produce the elements on the fly (as you are iterating over them) , whereas list(range(0,3)) produces a list (by iterating over all the elements and appending to the list internally) .

Example -

>>> range(0,3)
range(0, 3)
>>> list(range(0,3))
[0, 1, 2]

Ideally, if you only want to iterate over that range of values , range(0,3) would be faster than (list(range(0,3)) because the latter has the overhead of producing a list before you start iterating over it.

In Python 2.x , range(0,3) produces an list, instead we also had an xrange() function that has similar behavior of range() function from Python 3.x (xrange was renamed to range in Python 3.x)

For Python 3.5, From the documentation -

Range objects implement the collections.abc.Sequence ABC, and provide features such as containment tests, element index lookup, slicing and support for negative indices

So you can do things like -

>>> range(0,10)[5]
5
>>> range(0,10)[3:7]
range(3, 7)
>>> 5 in range(6,10)
False
>>> 7 in range(1,8)
True

And all of these are constant time operations , as can be seen from this test -

In [11]: %timeit a = xrange(0,1000000)[1000]
1000000 loops, best of 3: 342 ns per loop

In [12]: %timeit a = xrange(0,1000000)[10000]
1000000 loops, best of 3: 342 ns per loop

In [13]: %timeit a = xrange(0,1000000)[100000]
1000000 loops, best of 3: 342 ns per loop

In [14]: %timeit a = xrange(0,1000000)[999999]
1000000 loops, best of 3: 342 ns per loop

In [15]: %timeit a = xrange(0,10000000)[9999999]
1000000 loops, best of 3: 339 ns per loop

In [16]: %timeit a = xrange(0,1000000000000)[9999999999]
1000000 loops, best of 3: 341 ns per loop
2 of 6
13

It depends on what version of Python you are using.

In Python 2.x, range() returns a list, so they are equivalent.

In Python 3.x, range() returns an immutable sequence type, you need list(range(0,2)) to get a list.

Top answer
1 of 6
54

A "for loop" in most, if not all, programming languages is a mechanism to run a piece of code more than once.

This code:

for i in range(5):
    print i

can be thought of working like this:

i = 0
print i
i = 1
print i
i = 2
print i
i = 3
print i
i = 4
print i

So you see, what happens is not that i gets the value 0, 1, 2, 3, 4 at the same time, but rather sequentially.

I assume that when you say "call a, it gives only 5", you mean like this:

for i in range(5):
    a=i+1
print a

this will print the last value that a was given. Every time the loop iterates, the statement a=i+1 will overwrite the last value a had with the new value.

Code basically runs sequentially, from top to bottom, and a for loop is a way to make the code go back and something again, with a different value for one of the variables.

I hope this answered your question.

2 of 6
25

When I'm teaching someone programming (just about any language) I introduce for loops with terminology similar to this code example:

for eachItem in someList:
    doSomething(eachItem)

... which, conveniently enough, is syntactically valid Python code.

The Python range() function simply returns or generates a list of integers from some lower bound (zero, by default) up to (but not including) some upper bound, possibly in increments (steps) of some other number (one, by default).

So range(5) returns (or possibly generates) a sequence: 0, 1, 2, 3, 4 (up to but not including the upper bound).

A call to range(2,10) would return: 2, 3, 4, 5, 6, 7, 8, 9

A call to range(2,12,3) would return: 2, 5, 8, 11

Notice that I said, a couple times, that Python's range() function returns or generates a sequence. This is a relatively advanced distinction which usually won't be an issue for a novice. In older versions of Python range() built a list (allocated memory for it and populated with with values) and returned a reference to that list. This could be inefficient for large ranges which might consume quite a bit of memory and for some situations where you might want to iterate over some potentially large range of numbers but were likely to "break" out of the loop early (after finding some particular item in which you were interested, for example).

Python supports more efficient ways of implementing the same semantics (of doing the same thing) through a programming construct called a generator. Instead of allocating and populating the entire list and return it as a static data structure, Python can instantiate an object with the requisite information (upper and lower bounds and step/increment value) ... and return a reference to that.

The (code) object then keeps track of which number it returned most recently and computes the new values until it hits the upper bound (and which point it signals the end of the sequence to the caller using an exception called "StopIteration"). This technique (computing values dynamically rather than all at once, up-front) is referred to as "lazy evaluation."

Other constructs in the language (such as those underlying the for loop) can then work with that object (iterate through it) as though it were a list.

For most cases you don't have to know whether your version of Python is using the old implementation of range() or the newer one based on generators. You can just use it and be happy.

If you're working with ranges of millions of items, or creating thousands of different ranges of thousands each, then you might notice a performance penalty for using range() on an old version of Python. In such cases you could re-think your design and use while loops, or create objects which implement the "lazy evaluation" semantics of a generator, or use the xrange() version of range() if your version of Python includes it, or the range() function from a version of Python that uses the generators implicitly.

Concepts such as generators, and more general forms of lazy evaluation, permeate Python programming as you go beyond the basics. They are usually things you don't have to know for simple programming tasks but which become significant as you try to work with larger data sets or within tighter constraints (time/performance or memory bounds, for example).

[Update: for Python3 (the currently maintained versions of Python) the range() function always returns the dynamic, "lazy evaluation" iterator; the older versions of Python (2.x) which returned a statically allocated list of integers are now officially obsolete (after years of having been deprecated)].

🌐
Stack Overflow
stackoverflow.com › questions › 70816436 › meaning-of-the-rangerow-1-1
python - meaning of the range(row,-1,-1) - Stack Overflow
It starts at row and counts down to 0. Remember that the ending value in a range is exclusive. So, the zip will give you (row,col) then (row-1,col-1) then (row-2,col-2), until one of the two goes to zero.
Top answer
1 of 3
4

well, from the help:

>>> help(range)
range(...)
    range([start,] stop[, step]) -> list of integers

    Return a list containing an arithmetic progression of integers.
    range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
    When step is given, it specifies the increment (or decrement).
    For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!
    These are exactly the valid indices for a list of 4 elements.

so the last increment is not stop, but the last step before stop.

  • in countMe shouldn't the code go up till 18 ;
  • why is the last number printed in countMe 15, and not 18 ;
  • why is that in the second function oddsOut the function only founts till 7 for j and not 8 even though j is 8 ;
  • why is the last number printed in oddsOut 14.

more generally speaking the answer to those questions is that in most of the languages, a range is defined as [start:stop[, i.e. the last value of the range is never included, and the indexes start always at 0. The mess being that in a few languages and when working on algorithmics, ranges start at 1 and are inclusive with the last value.

In the end, if you want to include the last value you can do:

def closed_range(start, stop, step=1):
    return range(start, stop+1, step)

or in your example:

>>> def countMe(num):
>>>     for i in range(0, num+1, 3):
>>>         print (i)
>>> 
>>> countMe(18)
0
3
6
9
12
15
18
>>> 
2 of 3
2

The stop parameter in a range does not include that number for example

for i in range(0,5):
    print i

would print 0-4 but not 5.

🌐
Stack Overflow
stackoverflow.com › questions › 65465096 › how-does-a-loop-on-range-function-with-0-as-input-works
python - How does a loop on range function with 0 as input works? - Stack Overflow
The list contains numbers starting from 0 to the parameter, 0 included and the parameter excluded. ... When x is 0, then the list can't include 0 either. So you get the following: ... Since there are no values i can take, the loop doesn't run!
Find elsewhere
🌐
W3Schools
w3schools.com › python › ref_func_range.asp
Python range() Function
Python Examples Python Compiler ... Training ... The range() function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and stops before a specified number....
🌐
Stanford CS
cs.stanford.edu › people › nick › py › python-range.html
Python range() Function
The most common form is range(n), given integer n returns a numeric series starting with 0 and extending up to but not including n, e.g. range(6) returns 0, 1, 2, 3, 4, 5. With Python's zero-based indexing, the contents of a string length 6, are at index numbers 0..5, so range(6) will produce ...
🌐
Towards Data Science
towardsdatascience.com › home › latest › python range() built-in-function
Python range() built-in-function | Towards Data Science
January 17, 2025 - Then after quite a research, I came to know that the xrange is the incremental version of range according to stack overflow. One of them said that Python2 uses xrange() and Python3 uses range, so you don’ t have to worry about it. The range functions can also be used on the python list. An easy way to do this is as shown below: names = ['India', 'Canada', 'United States', 'United Kingdom'] for i in range(1, len(names)): print(names[i])
🌐
PYnative
pynative.com › home › python › python range() explained with examples
Python range() Function Explained with Examples
March 17, 2022 - If you notice, the result contains 5 elements which equal to len(range(0, 5)). Note, the index always starts from 0, not 1. If you want to include the end number in the result, i.e., If you want to create an inclusive range, then set the stop argument value as stop+step. ... # inclusive range start = 1 stop = 5 step = 1 # change stop stop += step for i in range(start, stop, step): print(i, end=' ') # Output 1 2 3 4 5 Code language: Python (python) Run
🌐
Stanford
web.stanford.edu › class › archive › cs › cs106a › cs106a.1204 › handouts › py-range.html
Python range() Function
The most common form is range(n), for integer n, which returns a numeric series starting with 0 and extending up to but not including n, e.g. range(5) returns 0, 1, 2, 3, 4. This is perfect for generating the index numbers into, for example, a string.. >>> s = 'Python' >>> len(s) 6 >>> for ...
🌐
CodeRivers
coderivers.org › blog › python-stack-overflow
Python Stack Overflow: A Comprehensive Guide - CodeRivers
February 22, 2026 - The error message usually provides some information about the function calls that led to the overflow. By examining the call stack in the error message, you can identify which functions are being called repeatedly or which deep nested calls are causing the problem. Proper Base Cases in Recursion: Always ensure that recursive functions have well-defined base cases that will be reached during execution. For example, in a factorial calculation: def factorial(n): if n == 0 or n == 1: return 1 else: return n * factorial(n - 1)
🌐
Real Python
realpython.com › python-range
Python range(): Represent Numerical Ranges – Real Python
November 24, 2024 - In Python, the range() function generates a sequence of numbers, often used in loops for iteration. By default, it creates numbers starting from 0 up to but not including a specified stop value. You can also reverse the sequence with reversed(). If you need to count backwards, then you can use a negative step, like range(start, stop, -1), which counts down from start to stop.