Python has two handy functions for creating lists, or a *range* of integers that assist in making `for`

loops.

These functions are `xrange`

and `range`

. But you probably already guessed that! 🙂

## The Difference Between xrange and Range in Python

Before we get started, let's talk about what makes `xrange`

and `range`

different.

For the most part, `xrange`

and `range`

are the exact same in terms of functionality. They both provide a way to generate a list of integers for you to use, however you please. The only difference is that `range`

returns a Python `list`

object and `xrange`

returns an `xrange`

object.

What does that mean? Good question! It means that `xrange`

doesn't actually generate a static list at run-time like `range`

does. It creates the values as you need them with a special technique called *yielding*. This technique is used with a type of object known as *generators*. If you want to read more in depth about generators and the yield keyword, be sure to checkout the article Python generators and the yield keyword.

Okay, now what does *that* mean? Another good question. *That* means that if you have a really gigantic range you'd like to generate a list for, say one billion, `xrange`

is the function to use. This is especially true if you have a really memory sensitive system such as a cell phone that you are working with, as `range`

will use as much memory as it can to create your array of integers, which can result in a `MemoryError`

and crash your program. It's a memory hungry beast.

That being said, if you'd like to iterate over the list multiple times, it's probably better to use `range`

. This is because `xrange`

has to generate an integer object every time you access an index, whereas `range`

is a static list and the integers are already "there" to use.

Alright, now on to the good stuff.

**What Does the xrange Function Do?**

Python’s xrange() function is utilized to generate a number sequence, making it similar to the range() function. But the main difference between the two functions is that the xrange() function is only available in Python 2, whereas the range() function is available in both Python 2 and 3.

The syntax of the xrange() function is:

*xrange (start,end,step)*

The parameters are used to define a range of numbers from start to finish, with the starting number being inclusive and the final number being exclusive.

The meaning of the three parameters is as follows:

**Start:**It specifies the beginning position of the number sequence.**End:**It specifies the ending position of the number sequence.**Step:**It specifies the difference between the numbers in the sequence.

It’s important to note that while the starting position and the step value may be defined optionally, the final position of the number sequence must always be defined.

**What Does the range Function Do?**

When a range of numbers is defined in the range() function, it returns the sequence of numbers between the defined range. The built-in function is typically used when programmers need to perform an action a specified number of times.

The range() function in Python 3 is essentially a renamed version of the xrange() function in Python 2. The function is typically used in conjunction with a for loop, and therefore, programmers that want to use the function must understand how the for loop works and how to use it.

A common usecase of the range() function is it is used to iterate the sequence type.

The syntax of the range() function is:

*range (start, stop, step)*

Users can decide where the number sequence will start and end and the difference between the numbers using the parameters. Using all the parameters is not mandatory – only the *stop* parameter is mandatory.

The meaning of the parameters is the essentially the same as the meaning of the parameters in the xrange() function:

**Start:**It is the integer that is the starting point of the number sequence.**Stop:**It is the integer before which the number sequence must be returned. The number sequence ends at the value “stop – 1.”**Step:**It is the integer value that defines the increment between the numbers in the number sequence.

**Advantages of range and xrange**

The main advantage of using the range() function is that it is more efficient. It can iterate over the same number sequence multiple times quickly.

In contrast, the xrange() function needs to reconstruct the integer object for every iteration of the number sequence.

The range() function uses real integer objects; hence, it performs poorly in terms of the memory it uses. That being said, the xrange() function cannot be used in every situation that requires a real list since it doesn’t support slices or list methods.

Moving on to the main advantage of the xrange() function – the xrange() object. The xrange() object takes up the same amount of memory regardless of the size of the defined range.

It is referred to as an opaque sequence type, yielding the same values as the corresponding list without storing the numbers simultaneously. In terms of performance, the xrange() function performs better when iterating a large number sequence.

**Different Ways of Using the xrange Function**

There are three different ways of using the xrange() function: with only the stop argument, using both the start and stop arguments, and using all the arguments.

**#1 Using the xrange Function with the Stop Argument**

The xrange() function can be defined using only the stop argument since the start and step arguments are optional. If a Python user only passes one argument, Python assumes it is the stop value, and the default value of the start and step parameters are set to 0 and 1, respectively.

For instance, if you want to print the number sequence from 0 to 9, you must pass “10” to the xrange() function as the stop argument. Since the stop value is an exclusive value, the function will only generate numbers until 9.

n = xrange(10) print(list(n))

The print statement is required since the output of xrange(10) must be converted into a list explicitly. The output of the script above would be:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

**#2 Using the xrange Function with Start and Stop Arguments**

When a user passes two arguments to the xrange() function, Python assumes that the values indicate the start and stop values. Since the step argument is not defined, it defaults to 1.

Let’s assume you want to print a number sequence from 10 to 19. To do this, you must define the start value as 10, since the start parameter is inclusive. On the other hand, since the stop value is exclusive, you must pass “20” as the parameter.

n = xrange(10,20) # converting n into a list and printing the list print(list(n))

The output of the script would be:

[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

**#3 Using the xrange Function with Start, Stop and Step Arguments**

When a user passes all three parameters to the xrange() function, no default values are considered for any of the arguments.

For instance, if you want to print numbers from 20 to 30, you must pass 20 as the start parameter, 31 as the stop parameter, and 1 as the step size.

n = xrange(20,31,1) # converting n into a list and printing the list print(list(n))

The script would print the number sequence:

[20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]

**Different Ways of Using the range Function**

Just like the xrange() function, the range() function can be used in three ways:

**#1 range(stop)**

If a user passes only a single argument to the range() function, Python assumes that it is the stop value. Python then generates a number sequence from 0 to the number before the stop value.

For example, to print the ten numbers starting from 0 and ending at 9, you must run the following code:

for i in range(10): print(i, end=' ') # Output 0 1 2 3 4 5 6 7 8 9

It’s important to note that the start value defaults to 0, and the step value defaults to 1. Additionally, if the stop value is set to 0 or any negative value, the range() function returns an empty sequence.

**#2 range(start, stop)**

When a user passes two arguments to the range() function, Python assumes that the arguments are start and stop. The function generates a sequence starting at the start value and ending at stop – 1.

For example, if you want to print a number sequence from 10 to 15, you would use the following script:

for i in range(10, 16): print(i, end=' ') # Output 10 11 12 13 14 15

It’s important to note that the step value defaults to 1, and that the range() function returns an empty sequence if the stop value is lesser than the start value.

**#3 range(start, stop, step)**

When a user passes all three arguments to the range() function, it returns a number sequence that begins at the start value, increments by the step value, and ends before the stop value.

For example, if you want to print a sequence starting from 10 and ending at 45 with an increment of five between the numbers in the sequence, you would use the following script:

for i in range(10, 50, 5): print(i, end=' ') # Output 10 15 20 25 30 35 40 45

It’s important to note that Python will throw a ValueError exception if the step value is set to 0.

# How to Use Python's range and xrange

So how do we use `range`

and `xrange`

? Here is the simplest example:

[python] >>> for i in xrange(10): ... print(i) ... 0 1 2 3 4 5 6 7 8 9 [/python]

Great! Simple enough. Note that you could also use `range`

in place of `xrange`

here, but I personally like `xrange`

better. Maybe it's that sexy "x" in the front. 🙂

Alright, explanation time. The functions `xrange`

and `range`

take in three arguments in total, however two of them are optional. The arguments are "start", "stop" and "step". "start" is what integer you'd like to start your list with, "stop" is what integer you'd like your list to stop at, and "step" is what your list elements will increment by.

## Python's xrange and range with Odd Numbers

Say we wanted only odd numbers. Here's what we could do:

[python] >>> for i in xrange(1, 10, 2): ... print(i) ... 1 3 5 7 9 [/python]

We told Python that we would like the first element to be one, the last element to be one less than ten, and that we'd like each element to go up by two. Really simple stuff.

## Python's xrange and range with Negative Numbers

Alright, so what about if we want a negative list?

Simple. Here's an example:

[python] >>> for i in xrange(-1, -10, -1): ... print(i) ... -1 -2 -3 -4 -5 -6 -7 -8 -9 [/python]

That's it! All we have to do is change the "start", "stop" and "step" to negative numbers. Awesome. Please note that you must do it this way for negative lists. Trying to use `xrange(-10)`

will not work because `xrange`

and `range`

use a default "step" of one.

## Another Python xrange and range Example

Here's one more example of even numbers between 100 and 120:

[python] >>> for i in xrange(100, 120, 2): ... print(i) ... 100 102 104 106 108 110 112 114 116 118 [/python]

And that's pretty much it for `xrange`

and `range`

. If you would like a more technical explanation of what these two functions do, please consult the Python docs for xrange and range.

Note that if "start" is larger than "stop", the list returned will be empty. Also, if "step" is larger that "stop" minus "start", then "stop" will be raised to the value of "step" and the list will contain "start" as its only element.

Here's a clearer picture:

[python] >>> for i in xrange(70, 60): ... print(i) ... # Nothing is printed >>> for i in xrange(10, 60, 70): ... print(i) ... 10 [/python]

# Deprecation of Python's xrange

One more thing to add. In Python 3.x, the `xrange`

function does not exist anymore. The `range`

function now does what `xrange`

does in Python 2.x, so to keep your code portable, you might want to stick to using `range`

instead. Of course, you could always use the 2to3 tool that Python provides in order to convert your code, but that introduces more complexity.

The reason why `xrange`

was removed was because it is basically always better to use it, and the performance effects are negligible. So Python 3.x's `range`

function *is* `xrange`

from Python 2.x.

You can find the PEP document here for reasoning why it was removed.

Over and out, soldier. Over and out.