In Python, you can use the built-in **range()** function to generate a range of numbers from a start point to an end point.

For instance, let’s create a range of numbers from 0 to 5 and print them out:

numbers = range(0,6) for number in numbers: print(number)

Output:

0 1 2 3 4 5

Notice how the last number in the **range()** call is **6**. This means the last number included in the range is actually **5**.

In Python, you can call the **range()** function with one, two, or three parameters.

Here are some examples:

# Range from 0 to 9 range(10) # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 # Range from 5 to 9 range(5, 10) # 5, 6, 7, 8, 9 # Range from 1 to 100 with step size of 10 range(0, 110, 10) # 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 # Reversed range from 100 to 0 with step size of -10. range(100, -10, -10) # 100, 90, 80, 70, 60, 50, 40, 30, 20, 10

If you’re looking for a short answer, I’m sure the above examples help you. But to truly learn how to use the **range()** function in different situations, I recommend reading the entire post.

This is a comprehensive guide to the **range()** function in Python. In this guide, you will learn thoroughly how to use the **range()** function in Python.

## The range() Function in Python

In Python, the built-in **range()** function produces an immutable sequence of numbers between start and end values.

The complete syntax of using** range()** function is as follows:

range(start, stop, step)

Where:

**start**is the lower limit for the range. This is an optional parameter with a default value of 0.**stop**is the upper limit for the range. The range consists of numbers until this value. Notice how it never includes the stop value in the range!**step**is the step size for the range. This is an optional argument that defaults to 1. Each number in the range is generated by adding**step**to the previous value.

The** range()** function returns a **range** object. You can loop through this **range** object with a for loop. It is also possible to convert the range object into a list.

In Python 3, there are three syntactical variations of how to use the **range()** function:

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

Let’s go through each of these alternatives in more detail.

### 1. range(start)

The most basic way to use the **range()** function in Python is by specifying only the end value for the range.

range(stop)

When you do this, the range automatically starts from 0 and takes steps of size 1. It ends one before the **stop** value.

For example, let’s generate a range of numbers from 0 to 5:

numbers = range(6) for number in numbers: print(number)

Output:

0 1 2 3 4 5

Here the range starts from 0 because you did not specify a starting value. The range ends at the value of 5 instead of 6 due to the exclusive nature of **range()** function.

### 2. range(start, stop)

Another way you can call the **range()** function in Python is by specifying both **start** and **stop** values. This is useful if you want the range to start from a value other than 0, which commonly is the case.

range(start, stop)

For instance, let’s generate values from 5 to 10:

numbers = range(5,11) for number in numbers: print(number)

Output:

5 6 7 8 9 10

Notice that the start value **5** is included in the range, but the end value **11** is not. This might cause confusion if it’s your first time using the **range()** function.

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

The third option to call the** range()** function is by specifying **start**, **stop**, and **step** parameters.

range(start, stop, step)

The **step** parameter sets the interval for the range. In other words, it affects the way the range is generated by adding a value other than 1 to the previous number.

For example, let’s generate a range of values from 50 to 100 with by using 10 as a step size:

numbers = range(50,110,10) for number in numbers: print(number)

Output:

50 60 70 80 90 100

### The range() Function Return Value

Now that you know how to use the **range()** function in Python, let’s take a closer look at the return value.

**In Python, the range() function returns a range object.**

For example, let’s create a range of numbers and print the object. Let’s also print the type of the range using the built-in **type()** function:

numbers = range(5, 10) print(numbers) print(type(numbers))

Output:

range(5, 10) <class 'range'>

The result of printing the range is not a list of numbers as you might expect. Instead, it’s a **range** object. In other words, the **range()** function returns a special **range** object.

The **range** object is iterable by nature. This means you can loop through it like any other **iterable**, such as a list. This is what you already saw in the previous examples.

Of course, you can also convert the **range** object into another iterable type, such as a list.

For example, let’s generate a range of numbers and convert it to a list with the built-in **list()** function:

numbers = range(50,110,10) numbers_list = list(numbers) print(numbers_list)

Output:

[50, 60, 70, 80, 90, 100]

Now the result is a regular Python list instead of a **range** object. So if you need to generate a range as a list, you can easily cast the **range** object into a list.

Keep in mind the range object is a range object for performance reasons. If there’s no need to cast the range to a list, don’t do it!

## Reversed Range in Python

In Python, it is possible to create a reversed range by specifying a negative step size to the **range()** function call.

For example, let’s generate a range of numbers from 100 to 50:

numbers = range(100, 40, -10) for number in numbers: print(number)

Output:

100 90 80 70 60 50

Make sure you understand why this works.

- The range starts from the
**start**parameter, but it stops one step before the**stop**parameter. Thus the stop is set to 40 to include 50 in the range. - As the
**step**is -10, the range takes steps of size -10. In other words, it decreases the**start**by 10 until the**stop**value.

But why do you need to specify the **step** value at all? How about **range(100, 40)**?

- As you remember, the
**range(100, 40)**would mean that the**step**is 1 (by default) which would mean**range(100, 40, 1)**. - This confuses Python as it tries to get from 100 to 40 by adding ones to 100, which is impossible.
- Thus the result is an empty
**range**.

numbers = range(100, 40) numbers_list = list(numbers) print(numbers_list)

Output:

[]

## Negative Range in Python

In Python, you can use the built-in** range()** function to produce a range of negative numbers.

When speaking about negative ranges in Python, you may refer to:

- Negative range with increasing numbers, that is, a positive
**step**. - Negative range with decreasing numbers, that is, a negative
**step**.

Let’s see an example of each.

### Negative Range with Increasing Numbers

For example, let’s create a range of numbers from -1 to -5:

numbers = range(-1, -6, -1) for number in numbers: print(number)

Output:

-1 -2 -3 -4 -5

Notice how you need a negative step size to make the range work. This is because it is not possible to get smaller values by adding positive values.

In other words, if you did not specify a negative **step**:

numbers = range(-1, -6) print(list(numbers))

Your result would be an empty range, that is, no values at all:

[]

### Negative Range with Increasing Numbers

To produce a range of negative values in increasing order, use the built-in** range() **function the same as you use it with positive numbers.

For example, let’s create a range of negative numbers from -10 to -5.

numbers = range(-10, -4) for number in numbers: print(number)

Output:

-10 -9 -8 -7 -6 -5

Notice how the **step** parameter is not needed as you are increasing the numbers by one.

## Range Indexing in Python

In Python, the **range()** function produces a **range** object. This **range** object supports indexing the same way other iterables, such as lists, do.

For example, let’s get the second number in a range of numbers:

numbers = range(1, 6) # 1, 2, 3, 4, 5 second = numbers[1] print(second)

Output:

2

Needless to mention **range** objects support negative indexing too.

For example, let’s get the last element of a range using negative indexing -1:

numbers = range(1, 6) # 1, 2, 3, 4, 5 last = numbers[-1] print(last)

Output:

5

## Range Slicing in Python

Python **range** objects support slicing. This means you can get a partial group of numbers from a range using slicing.

When you slice a **range** object in Python, you get a range object as a result. This range object contains the part of the original range.

If you are unfamiliar with slicing in Python, feel free to check this article.

For example, let’s get the first 3 numbers in a range:

numbers = range(1, 10) first_three = numbers[0:3] for number in first_three: print(number)

Output:

range(1, 4)

A common way to use slicing in Python is to reverse an iterable with slicing by** [::-1]**. You can do the same for a range of numbers too.

For instance, let’s reverse a range of numbers from 1 to 5:

numbers = range(1, 6) rev = numbers[::-1] for number in rev: print(number)

Output:

5 4 3 2 1

## Inclusive Range

The Python **range()** function produces a range of values that does not include the last value by default.

For example **range(0,5)** produces a range of values **0, 1, 2, 3, 4**.

To create an inclusive range, that is, to add the stop value into the range too, add the **step** value to the **stop** value.

For example, let’s create a range of values from 1 to 5 inclusively:

step = 1 numbers = range(1, 5 + step, step) print(list(numbers))

Output:

[1, 2, 3, 4, 5]

## For Loops with range() in Python

A common way to utilize the** range()** function is with for loops.

### Loop Through Numbers with range()

The most basic use case is when looping through numbers from n to m.

For example, let’s print numbers from 1 to 5:

numbers = range(1,6) for number in numbers: print(number)

Output:

1 2 3 4 5

### Loop with an Index Using range() Function

Another common use case for the **range() **is to access the index (or indexes) of an element with a for loop.

For example, let’s print a list of names and their index in the list:

queue = ["Alice", "Bob", "Charlie", "David"] for pos in range(len(queue)): print(f"{pos}: {queue[pos]}")

Output:

0: Alice 1: Bob 2: Charlie 3: David

Although there’s a much better solution to get the indexes by using the enumerate() function. Let’s have a look at how this function works.

### Alternative to range() Function with For Loops

Now you know the** range()** can be used in a for loop to get the index of the elements. Meanwhile, this is commonly taught for beginners, it is not the ideal way to do it.

Instead, you should use a built-in** enumerate() **function.

For example, let’s repeat the example of printing the list of names and their index. Let’s not use** range()** this time, but **enumerate()** instead:

queue = ["Alice", "Bob", "Charlie", "David"] for pos, name in enumerate(queue): print(f"{pos}: {name}")

Output:

0: Alice 1: Bob 2: Charlie 3: David

In short, the** enumerate()** function couples the list elements with their index.

In the above example, the **enumerate(queue)** produces an object with position, name pairs:

[(0, 'Alice'), (1, 'Bob'), (2, 'Charlie'), (3, 'David')]

## Conclusion

Today you learned how to use the **range()** function in Python.

To recap, the **range()** function returns a range of values from **n** until **m**.

For example **range(5)** returns numbers 0,1,2,3,4.

The result of the **range()** function is a **range** object. You can use the **range** object to loop through the range. Alternatively, you can cast the range object to a list to get a list that represents a range of numbers.

There are three ways to call the range function in Python:

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

Thanks for reading. Happy coding!