Which is the most efficient way to iterate through a list in python?

for item in list:

its obviously the one with fewer function calls.

If you want to get the index of items as you go use enumerate like this

for pos, item in enumerate(collection):

def loop_1(data):
    for i in range(len(data)):
        print(data[i])


def looper_2(data):
    for val in data:
        print(val)

Checking with dis gives us the following bytecode for loop_1:

 12       0 SETUP_LOOP              40 (to 43)
          3 LOAD_GLOBAL              0 (range)
          6 LOAD_GLOBAL              1 (len)
          9 LOAD_FAST                0 (data)
         12 CALL_FUNCTION            1
         15 CALL_FUNCTION            1
         18 GET_ITER            
    >>   19 FOR_ITER                20 (to 42)
         22 STORE_FAST               1 (i)

13       25 LOAD_GLOBAL              2 (print)
         28 LOAD_FAST                0 (data)
         31 LOAD_FAST                1 (i)
         34 BINARY_SUBSCR       
         35 CALL_FUNCTION            1
         38 POP_TOP             
         39 JUMP_ABSOLUTE           19
    >>   42 POP_BLOCK           
    >>   43 LOAD_CONST               0 (None)
         46 RETURN_VALUE        

The bytecode for loop_2 looks like this:

17        0 SETUP_LOOP              24 (to 27)
          3 LOAD_FAST                0 (data)
          6 GET_ITER            
    >>    7 FOR_ITER                16 (to 26)
         10 STORE_FAST               1 (val)

18       13 LOAD_GLOBAL              0 (print)
         16 LOAD_FAST                1 (val)
         19 CALL_FUNCTION            1
         22 POP_TOP             
         23 JUMP_ABSOLUTE            7
    >>   26 POP_BLOCK           
    >>   27 LOAD_CONST               0 (None)
         30 RETURN_VALUE

The second version is obviously better.