In Python, you can use the built-in **range()** function to generate a range of numbers from the starting point until the 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

The last number in the **range()** call is 6, which 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

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

## 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.

### range(start)

When using the **range()** function, it is possible to only specify the **stop** 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. Then it ends at 5 due to the exclusive nature of **range()** function.

### 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 do not want the range to start at 0.

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

### 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 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 10 number intervals:

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

Output:

50 60 70 80 90 100

### The range() Function Return Value

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

For example, let’s create a range of numbers and print it directly. 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'>

As you can see, the result of printing the range just prints the range as-is. It does not spit out a list or a list-like sequence of numbers to the screen. This is because **range()** returns a **range** object.

This **range** object is an object that stores a range of numbers. It is thus not a list or tuple and has nothing to do with them.

The **range** object is iterable, though. 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.

Another option is to convert the **range** object into another iterable type in Python, 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]

## 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 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,
**range(100, 40)**would mean that the**step**is 1 (by default). - In other words, leaving the negative
**step**out 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() **function with for loops is to get the index of the element.

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

### 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')]

To learn more about** enumerate()**, please read this article.

## 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!