In python-3.x a range(..) is an object, it does not construct a list. If you perform member checks with an int as item, then it can do that quite fast. The algorithm is a bit complicated, since there are both positive and negative steps. You can look it up on [GitHub]. A simple algorithm with a positive step count (c > 0) for x in range(a, b, c) is something like:

x ≥ a ∧ x < b ∧ mod(x-a, c) = 0.

For a negative step count (c < 0) is is quite similar:

x ≤ a ∧ x > b ∧ mod(x-a, c) = 0.

If we consider the comparisons to be done in O(1) and calculating the modulo as well, it is an O(1) algorithm. In reality for huge numbers, it scales in the number of digits of the numbers, so it is an O(log n) algorithm.

This however only works for ints. Indeed, in case you use floats, complex, other numerical or non-numerical types, it does not perform the above calculations. It will then fall back on iterating over the range(..) object. Which of course can take considerable time. If you have a range of a million elements, it will thus iterate over all these elements and eventually reach the end of the range, and return False, or find a match, and return True. In the future, perhaps some extra functionality can be implemented for some numerical types, but one can not do this in general, since you can define your own numerical type with an equality operation that works differently.

In python-2.x, range(..) is a function that returns a list. Indeed:

>>> range(15)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> type(range(15))
<type 'list'>

In order to check if an element is a member of a list, it will iterate over the list, and check equality for all items until it finds an element that is equal, or the list is exhausted. If we consider checking if two items are equal to be constant time, then this takes linear time O(n). In reality for huge numbers, checking if two numbers are equal, scales linear with the number of "digits", so O(log m) with m the value of that number.

python-2.x has an xrange(..) object as well, but this does not check for membership with the above demonstrated trick.

Answer from willeM_ Van Onsem on Stack Overflow
Top answer
1 of 1
16

In python-3.x a range(..) is an object, it does not construct a list. If you perform member checks with an int as item, then it can do that quite fast. The algorithm is a bit complicated, since there are both positive and negative steps. You can look it up on [GitHub]. A simple algorithm with a positive step count (c > 0) for x in range(a, b, c) is something like:

x ≥ a ∧ x < b ∧ mod(x-a, c) = 0.

For a negative step count (c < 0) is is quite similar:

x ≤ a ∧ x > b ∧ mod(x-a, c) = 0.

If we consider the comparisons to be done in O(1) and calculating the modulo as well, it is an O(1) algorithm. In reality for huge numbers, it scales in the number of digits of the numbers, so it is an O(log n) algorithm.

This however only works for ints. Indeed, in case you use floats, complex, other numerical or non-numerical types, it does not perform the above calculations. It will then fall back on iterating over the range(..) object. Which of course can take considerable time. If you have a range of a million elements, it will thus iterate over all these elements and eventually reach the end of the range, and return False, or find a match, and return True. In the future, perhaps some extra functionality can be implemented for some numerical types, but one can not do this in general, since you can define your own numerical type with an equality operation that works differently.

In python-2.x, range(..) is a function that returns a list. Indeed:

>>> range(15)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> type(range(15))
<type 'list'>

In order to check if an element is a member of a list, it will iterate over the list, and check equality for all items until it finds an element that is equal, or the list is exhausted. If we consider checking if two items are equal to be constant time, then this takes linear time O(n). In reality for huge numbers, checking if two numbers are equal, scales linear with the number of "digits", so O(log m) with m the value of that number.

python-2.x has an xrange(..) object as well, but this does not check for membership with the above demonstrated trick.

Discussions

python - Help with Time Complexity - Computer Science Stack Exchange
What is the proper way to evaluate the time complexity of this function? ... $\begingroup$ Could you please rewrite your code as pseudocode so people don't have to understand what the range command does in Python? More on cs.stackexchange.com
🌐 cs.stackexchange.com
October 7, 2018
What is the worst-case time complexity for the following Python fragment? for i in range(n): work(...) Assume that work(...) is O(n). In this question, the detail about the arguments to the function are not important, so they are shown as (...) O 0(1) O O(2n) O O(n) O O(n) O O(n) Question 10 1 pts What is the worst-case time complexity for the following
Answer to What is the worst-case time complexity for the More on chegg.com
🌐 chegg.com
1
March 11, 2022
python 3.x - "Largest range" - what is the time complexity? - Stack Overflow
The question is to find the longest range of integers in the array and print an array with the first int and the last int in this range. I wrote the code successfully but I'm new at this algorithm topic and I'm having trouble understanding what is the time complexity of my own code, is it O(n**2) ... More on stackoverflow.com
🌐 stackoverflow.com
October 19, 2020
runtime analysis - What is the time complexity of this algorithm? - Computer Science Stack Exchange
In Python 3, n = 10 count=0 for i in range (1, n+1): for j in range (1, i+1): for k in range (1, j+1): count+=3 print(count) 660 · The more intricate summation of (i + j + k) over k from 1 to j, j from 1 to i, and i from 1 to n, equals (n4 + 4*n3 + 5*n**2 + 2*n) / 4, which is exactly (n+1)/2 times ... More on cs.stackexchange.com
🌐 cs.stackexchange.com
April 23, 2016
🌐
Pythoncomplexity
pythoncomplexity.com › builtins › range
Range - Python Big-O: Time & Space Complexity
# Membership check is O(1) - solves equation r = range(10, 100, 5) 50 in r # O(1) - True (10 + 5*k = 50) 51 in r # O(1) - False (no integer k works) # Much faster than list lst = list(range(10, 100, 5)) 50 in lst # O(n) - linear search
🌐
UCI
ics.uci.edu › ~pattis › ICS-33 › lectures › complexitypython.txt
The Complexity of Python Operators/Functions
The latter two are both O(1), and computing len(alist) is also O(1), so the complexity of range(len(alist)) is O(1)+O(1)+O(1) = O(1). The complexity class for executing the entire function is O(N) * O(N) + O(1) = O(N**2). So we know from the previous lecture that if we double the length of ...
🌐
Leyaa
leyaa.ai › codefly › learn › python › part-1 › python-iteration-using-range › complexity
Iteration using range() in Python Time Complexity - Big O Analysis | Leyaa.ai
When we use range() to repeat actions, it is important to know how the time needed grows as the number of repeats increases. We want to understand how the work changes when the range gets bigger. ... Analyze the time complexity of the following code snippet.
🌐
Medium
medium.com › data-science › understanding-time-complexity-with-python-examples-2bda6e8158a7
Understanding time complexity with Python examples | by Kelvin Salton do Prado | TDS Archive | Medium
February 15, 2020 - This is the best possible time complexity when the algorithm must examine all values in the input data. For example: ... Let’s take a look at the example of a linear search, where we need to find the position of an element in an unsorted list: def linear_search(data, value): for index in range(l...
Find elsewhere
🌐
Shodan
skerritt.blog › big-o
All You Need to Know About Big O Notation [Python Examples]
June 21, 2023 - This looks confusing but is just a fancy way of saying that the function (algorithm) is part of another function (the Big O notation used). Simplifying again: Our algorithm falls within the range of a Big O notation time complexity (O(n), O(log n), ...
🌐
Stack Abuse
stackabuse.com › big-o-notation-and-algorithm-analysis-with-python-examples
Big O Notation and Algorithm Analysis with Python Examples
November 27, 2023 - We will see how Big-O notation can be used to find algorithm complexity with the help of different Python functions. Note: Big-O notation is one of the measures used for algorithmic complexity. Some others include Big-Theta and Big-Omega. Big-Omega, Big-Theta, and Big-O are intuitively equal to the best, average, and worst time complexity an algorithm can achieve.
🌐
Analytics Vidhya
analyticsvidhya.com › home › python range() function
Python range() function - Analytics Vidhya
April 3, 2024 - The time complexity of the range() function is constant, regardless of the size of the range. This makes it efficient for large-scale applications. The range() function has some advantages over other iteration techniques in Python.
🌐
Python
wiki.python.org › moin › TimeComplexity
TimeComplexity - Python Wiki
This page documents the time-complexity (aka "Big O" or "Big Oh") of various operations in current CPython. Other Python implementations (or older or still-under development versions of CPython) may have slightly different performance characteristics.
🌐
Finxter
blog.finxter.com › home › learn python blog › complexity of python operations
Complexity of Python Operations - Be on the Right Side of Change
May 29, 2020 - Given input size n, you can describe the complexity of your algorithm with a function of the input n → f(n) that defines the number of “resource units” (e.g., time, memory) needed to finish it (worst-case or average-case).
🌐
USACO
usaco.guide › home › bronze › time complexity
Time Complexity · USACO Guide
In Big O notation, we denote the complexity of a function as ... The time complexity of loops is the number of iterations that the loop runs.
🌐
Integralist
integralist.co.uk › posts › algorithmic-complexity-in-python
Algorithmic Complexity in Python | integralist
February 2, 2019 - Asymptotic analysis is the computing of an algorithm’s running time, and there are actually a few different variations that allow us to measure different aspects of that running time: Big Omega: represents the lower bound. Big Theta: represents both the lower and upper bounds. Big O: represents the upper bound. We’re interested in the last notation in that list (Big O notation) and what the various algorithmic complexity symbols mean when applied to simplified implementations of specific algorithms written in Python.