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
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.
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() .
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.
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().
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]
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With