-2

Sorry, kind of a hard question to title.

If I want to iterate over a potentially empty list, which is more efficient? I'm expecting the list to be empty the majority of the time.

for x in list: 
    dostuff()

OR

if len(list)>0:
     for x in list:
        dostuff()
shaktimaan
  • 11,962
  • 2
  • 29
  • 33
user3727843
  • 574
  • 1
  • 4
  • 13
  • 5
    No offense, but this kind of question is among the least productive ones that one can possibly ask. Not only is it astonishingly unlikely that any performance difference actually matters in the slightest, if it did you should be addressing this by **benchmarking** instead of asking or guessing. *Reasoning* about performance doesn't even work very well when looking at C code and knowing the entire stack of hardware and software involved. It works even worse when looking at Python code and not knowing much about hardware and the Python implementation. –  Jun 10 '14 at 22:03

4 Answers4

2

Based on timings from the timeit module:

>>> from timeit import timeit
>>> timeit('for x in lst:pass', 'lst=[]')
0.08301091194152832
>>> timeit('if len(lst)>0:\n  for x in lst:\n    pass', 'lst=[]')
0.09223318099975586

It looks like just doing the for loop will be faster when the list is empty, making it faster option regardless of the state of the list.

However, there is a significantly faster option:

>>> timeit('if lst:\n  for x in lst:\n    pass', 'lst=[]')
0.03235578536987305

Using if lst is much faster than either checking the length of the list or always doing the for loop. However, all three methods are quite fast, so if you are trying to optimize your code I would suggest trying to find what the real bottleneck is - take a look at When is optimisation premature?.

Community
  • 1
  • 1
Rob Watts
  • 6,866
  • 3
  • 39
  • 58
1

You can just use if list:

In [15]: if l:
   ....:     print "hello"
   ....:     

In [16]: l1= [1]

In [17]: if l1:
   ....:     print "hello from l1"
   ....:     
hello from l1

In [21]: %timeit for x in l:pass
10000000 loops, best of 3: 54.4 ns per loop

In [22]: %timeit if l:pass
10000000 loops, best of 3: 22.4 ns per loop

If a list is empty if list will evaluate to False so no need to check the len(list).

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
1

Firstly if len(list) > 0: should be if list: to improve readability. I personally would have thought having the if statement is redundant but timeit seems to prove me wrong. It seems (unless I've made a silly mistake) that having the check for an empty list makes the code faster (for an empty list):

$ python -m timeit 'list = []' 'for x in list:' '    print x'
10000000 loops, best of 3: 0.157 usec per loop

$ python -m timeit 'list = []' 'if list:' '    for x in list:' '        print x'
10000000 loops, best of 3: 0.0766 usec per loop
s16h
  • 4,647
  • 1
  • 21
  • 33
0

First variant is more efficient, because Python's for loop checks length of list anyway, making additional explicit check just a waste of CPU cycles.

CubiX
  • 119
  • 1
  • 3
  • 3
    Talk is cheap. Benchmarks is where it's at! (Also, you neglect the possibility that setting up a loop and stepping into the list methods takes longer than a Python-level length check.) –  Jun 10 '14 at 22:00
  • According to timeit, there is no difference at all, i.e. one could be sometimes faster, sometimes slower. First one shows 0.003286123275756836 and second shows 0.0032868385314941406 over 10000 loops. – CubiX Jun 10 '14 at 22:07