5

I have started learning python and now learning python for loop. I am using online source to learn python. But i am little but confused about for loop.

The output of

list = ["geeks", "for", "geeks"]
for index in range(len(list)):
    print (list[index])

and

list = ["geeks", "for", "geeks"]
for i in list:
    print(i)

are same then why to use range(len) method?

Thanks in advance.

Alex44
  • 61
  • 1
  • 1
  • 6
  • 1
    @user4815162342 Sorry, I completely forgot to select answer as best answer. Thanks for reminding – Alex44 Dec 11 '18 at 17:29

4 Answers4

10

For such simple case, for ind in range(len(sequence)) is generally considered an anti-pattern. The are cases when it's useful to have the index around, though, such as when you need to assign back to the list:

for ind in range(len(lst)):
    elem = lst[ind]
    # ... Do some processing
    lst[ind] = processed_elem

Even in that case, range(len(...)) is better expressed with enumerate:

for ind, elem in enumerate(lst):
    # ... Do some processing
    lst[ind] = processed_elem

Also, as already pointed out in a comment, it's recommended to avoid variable names that clash with built-ins, such as list.

user4815162342
  • 141,790
  • 18
  • 296
  • 355
  • Thanks for your kind help. Is there any best source to learn for loop? – Alex44 Nov 18 '18 at 07:45
  • @Alex44 Just get a good book on Python, it will surely cover the `for` loop, as well as other things you'll need. – user4815162342 Nov 18 '18 at 07:47
  • There's no built-in `index` function. There's an `index` method on built-in sequence types, but there's no risk of clashing with that. – user2357112 Nov 18 '18 at 08:04
  • @user2357112 I don't have money to buy book. Thats why i chose online source to learn python. – Alex44 Nov 18 '18 at 08:09
  • @user2357112 Thanks for the correction, I was referring to the functionality provided by `operator.index`, which is not a built-in. I've corrected the answer. – user4815162342 Nov 18 '18 at 08:44
  • These examples could be replaced by a shorter and more pythonic `lst = [some_processing(elem) for elem in lst]`, right? – Eric Duminil Nov 18 '18 at 08:46
  • @Alex44 If you don't have the money to buy a book, consider borrowing or looking for cheap download options (I was also without money while studying). Asking questions on SO is a great resource for when you have an actual problem, but it's **not** a substitute for going through a textbook. – user4815162342 Nov 18 '18 at 08:48
  • check this list of free python resources https://python-forum.io/Thread-A-List-of-Free-Python-Resources – buran Nov 18 '18 at 08:51
  • 1
    @EricDuminil That creates a new list, which may or may not be what you want. Also, there could be other reasons to use the `for` loop, such as processing not fitting a single expression, or needing to use control flow statements such as `break`, `continue`, `return`, `raise`, `with` and others inside the loop body. – user4815162342 Nov 18 '18 at 08:53
2

you should never use the first one, it's non-pythonic. Use the second one. If for whatever reason you need the index, use enumerate, e.g.

for index, item in enumerate(some_list):
    print(f'Item with index {index} is {item}')
buran
  • 13,682
  • 10
  • 36
  • 61
2

While the latter is definitiely the way to go as long as it fits your needs since its clear and pythonic, there are cases where you really need the index of the element.

One example are sorting algorithms, like this BubbleSort here (src):

def bubbleSort(arr):
    n = len(arr)

    # Traverse through all array elements
    for i in range(n):

        # Last i elements are already in place
        for j in range(0, n-i-1):

            # traverse the array from 0 to n-i-1
            # Swap if the element found is greater
            # than the next element
            if arr[j] > arr[j+1] :
                arr[j], arr[j+1] = arr[j+1], arr[j]

Here the list indices of sequential elements are used to swap their positions in the list if their sort order is incorrect, while the position in the list is something the pure values of the elements in a for elem in arr loop don't have any connection to anymore. Therefore in such cases you won't get around using the range over the list's len or similar, so that's not un-pythonic by defintion.

Last but not least, a good combination if you need both the index and the value is Python's enumerate.

for index, value in enumerate(arr):
     print(index, value)

Although one could use it in the above BubbleSort example, you'd start mixing value variables with arr[index] expressions, which is not a good idea for the readability of the code. So here, too, it depends very much on the situation if it makes sense to use the one construct or the other, there's no definite choice.

Jeronimo
  • 2,268
  • 2
  • 13
  • 28
0

Like others, I can't think of many use cases for for idx in range(len(x)):. The only one that really pops to mind is if you need to remove elements from x over the course of the for loop (in which case, as pointed out in the comments, you should go backwards), or you want to do a number of loops equal to len(x) for some reason unconnected to operations on x.

But yes, generally don't use for _ in range(len(x)): if you are iterating over x.

NotAnAmbiTurner
  • 2,553
  • 2
  • 21
  • 44