Question

In Python which is better in terms of performance:

1)

for i in range(len(a[:-1])):
    foo()

or

2)

for i in range(len(a)-1):
    foo()

UPDATE:

Some context on why I'm looping over indices (non-idiomatic?):

for c in reversed(range(len(self._N)-1)):
    D[c] =  np.dot(self._W[c], D[c-1])*A[c]*(1-A[c])
Was it helpful?

Solution 2

range(0, len(a) - 1) should be more performant of the 2 options. The other makes an unnecessary copy of the sequence (sans 1 element). For looping like this, you might even get a performance boost by using xrange on python2.x as that avoids materializing a list from the range call.

Of course, you usually don't need to loop over indices in python -- There's usually a better way.

OTHER TIPS

The second one is better, two reasons:

  1. The first one created a new list a[:-1], which takes up unnecessary time & memory, the second one didn't create a new list.

  2. The second one is more intuitive and clear.

[:] returns a shallow copy of a list. it means that every slice notation returns a list which have new address in memory, but its elements would have same addresses that elements of source list have.

The expression a[:-1] creates a new list for which you take the length and discard the list. This is O(n) time and space complexity, compared to O(1) time and space complexity for the second example.

neither is the right way

for i,item in enumerate(a[:-1]):
    ...

is how you should probably do it ...

in general in python you should never do

 for i in range(len(a_list)):  ...

here are the timing differences

>>> timeit.timeit("for i in range(len(a)-1):x=i","a=range(1000000)",number=100)
3.30806345671283
>>> timeit.timeit("for i in enumerate(a[:-1]):x=i","a=range(1000000)",number=100
5.3319918613661201

as you can see it takes an extra 2 seconds to do 100 times on a large list of integers ... but its still a better idea imho

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top