Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: for loops - for i in range(0,len(list) vs for i in list

This is a really simple python mechanics question. Why can't I just say for i in range original_list instead of for i in range(0, len(original_list)). Do people usually use range over the former? Thanks!

# "If I give you an array with negative and positive numbers (i.e. {3,2,-3,6,4,-7}) and asked you to sort it so that the negative numbers appeared first but you didn't change the relative order of the remaining numbers, how would you do it? (i.e. the final result would be {-3,-7,3,2,6,4}).

original_list = [3, 2, -3, 6, 4, -7]
pos_list = []
neg_list = []

for i in range(0, len(original_list)):
    if original_list[i] < 0:
        neg_list.append(original_list[i])
    else:
        pos_list.append(original_list[i])

print neg_list + pos_list
like image 450
Intrepid Diamond Avatar asked Oct 04 '15 05:10

Intrepid Diamond


People also ask

What is difference between range and Len in Python?

Well, if len(list) is the length of a list, and range(N) is the integers from 0 to N-1, then range(len(list)) is the integers from 0 to 1 less than the length of the list, i.e., all the legal indices of the list.

Does for loop in Python work on range?

for loops repeat a block of code for all of the values in a list, array, string, or range() . We can use a range() to simplify writing a for loop. The stop value of the range() must be specified, but we can also modify the start ing value and the step between integers in the range() .

Why do we use range Len in Python?

The function len() is one of Python's built-in functions. It returns the length of an object. For example, it can return the number of items in a list. You can use the function with many different data types.

Is enumerate more efficient than range len ())?

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().


2 Answers

In your case, since you don't need to use the index of the items in the list, you can just iterate over it using for in:

>>> for item in original_list:
...     if item < 0:
...         ...

If you want to iterate over the indexes of items in your list, use for in range(..):

>>> for i in range(len(original_list)):
...     if original_list[i] < 0:
...         ...

Alternatively, you might also want to use enumerate() if you need both item and index in loop's body:

>>> for i, item in enumerate(original_list):
...    if item < 0:
...        ...

By this way, you also eliminate the use of original_list[i].

like image 169
Ozgur Vatansever Avatar answered Nov 14 '22 22:11

Ozgur Vatansever


The construction range(len(my_sequence)) is usually not considered idiomatic Python. It focuses your code on lower level mechanics than what we usually try to write, and this makes it harder to read. Because of this, using range here is mostly seen as a holder from people used to coding in lower level languages like C.

See, for example, Raymond Hettinger's talk Transforming Code into Beautiful Idiomatic Python - one of the first things he recommends is exactly changing for i in range(len(sequence)) into for item in sequence where ever it appears; he then goes on to mention enumerate and zip to cover situations where you might otherwise be tempted to revert to using range. He also mentions that the idiomatic way is faster. Aside from Python builtin types being (unsurprisingly) optimised to run idiomatic constructs quickly, it isn't hard to see why this could be true of certain other data structures - for example, a linked list can have much faster sequential than random access, meaning that loops relying on my_linked_list[i] could become a quadratic time operation rather than a linear one.

You can see similar advice from time to time if you follow the [python] tag over at codereview.SE.

like image 23
lvc Avatar answered Nov 14 '22 23:11

lvc