Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Complexity of enumerate

I see a lot of questions about the run-time complexity of python's built in methods, and there are a lot of answers for a lot of the methods (e.g. https://wiki.python.org/moin/TimeComplexity , https://www.ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt , Cost of len() function , etc.)

What I don't see anything that addresses enumerate. I know it returns at least one new array (the indexes) but how long does it take to generate that and is the other array just the original array?

In other words, I'm assuming it's O(n) for creating a new array (iteration) and O(1) for the reuse of the original array...O(n) in total (I think). Is the another O(n) for the copy making it O(n^2), or something else...?

like image 496
10'004 Avatar asked Jun 30 '15 00:06

10'004


People also ask

What is the time complexity of enumerate?

Benefit of Using Enumerate index is that it has a complexity of O(n) which means you'll be traversing the list more than a couple of times(also considering the for loop itself), and it then returns the starting index of a given item, which means you'll get incorrect results for lists with duplicate items.

Does enumerate increase time complexity?

Whether the actual time is 2n, 3n, 4n, 0.5n, or any multiple of n, the complexity is always O(n). @10'004: enumerate() may work with infinite generators and therefore it does not copy its input. Though it won't change the time complexity even if it did (for a finite input).

Is enumerate or range faster?

enumerate() is faster when you want to repeatedly access the list/iterable items at their index. When you just want a list of indices, it is faster to use len() and range().

Why is enumerate faster?

First using enumerate creates a enumerate object which one by one yields a result, thus being faster than iterating through a list once to find the value at that index (but its tiny, not to worry about).


2 Answers

The enumerate-function returns an iterator. The concept of an iterator is described here.

Basically this means that the iterator gets initialized pointing to the first item of the list and then returning the next element of the list every time its next() method gets called.

So the complexity should be:

Initialization: O(1)

Returning the next element: O(1)

Returning all elements: n * O(1)

Please note that enumerate does NOT create a new data structure (list of tuples or something like that)! It is just iterating over the existing list, keeping the element index in mind.

You can try this out by yourself:

# First, create a list containing a lot of entries:
# (O(n) - executing this line should take some noticeable time)
a = [str(i) for i in range(10000000)] # a = ["0", "1", ..., "9999999"]

# Then call the enumeration function for a.
# (O(1) - executes very fast because that's just the initialization of the iterator.)
b = enumeration(a)

# use the iterator
# (O(n) - retrieving the next element is O(1) and there are n elements in the list.)
for i in b:
    pass  # do nothing
like image 119
Felix Avatar answered Sep 22 '22 14:09

Felix


Assuming the naïve approach (enumerate duplicates the array, then iterates over it), you have O(n) time for duplicating the array, then O(n) time for iterating over it. If that was just n instead of O(n), you would have 2 * n time total, but that's not how O(n) works; all you know is that the amount of time it takes will be some multiple of n. That's (basically) what O(n) means anyway, so in any case, the enumerate function is O(n) time total.

like image 34
Sam Estep Avatar answered Sep 21 '22 14:09

Sam Estep