0

I'm confused with some python basics. I have my list:

myList = ['a','b','c','d','e','f']

now I would like to print this list using index and range:

for i in range(0, len(myList)):
    print(myList[i])

I got:

a
b
c
d
e
f

My first question: Why I shouldn't use len(myList)-1? len(myList) returns 6 but when I use directly print(myList[6]) I got out of range error. Why using this in for loop is different?

Second. I know I can use myList.reverse() but I would like to print reversed list like this:

for i in range(len(myList), 0, -1):
    print(myList[i])

I get out of range and I should add -1:

for i in range(len(myList)-1, 0, -1):
    print(myList[i])

but after this I got only:

f
e
d
c
b

My second question: where is "a"? ;) and why in this example I have to use len(myList)-1?

Mlody87
  • 425
  • 1
  • 7
  • 19
  • 2
    `range(0, n)` goes 0, 1, 2, .... n-1 (n not included) – rdas May 21 '20 at 10:21
  • `range(n, 0, -1)` goes n, n-1, n-2, .... 1 (0 not included). Point is: `range` does not include its end-point. – Mustafa Aydın May 21 '20 at 10:25
  • Note that idiomatically, one would just use ``for element in myList:`` and ``for element in reversed(myList):``. Likewise, you can just inspect the elements of ``range(len(myList))`` and others by printing ``i``. – MisterMiyagi May 21 '20 at 10:30
  • len() function return the number of elements in collections. So if you have 6 elements, it means last index will be 5. That's why you can't use myList[6] – Adil Shirinov May 21 '20 at 10:30

4 Answers4

1

The first prameter is inclusive, whereas the second parameter is exclusive. Which means if a range function is called like range(a,b) it would result in values between [a,b). Therefore when you use range(0, len(myList)), this loops through 0..len(myList)-1.

As you would have guessed by now, you need to subtract 1 while looping in reverse order because the last index of the array is len(myList) -1 and you are missing a because 0 is not included. Therefore, if you wish to iterate in reverse order, you could do range(len(myList)-1, -1, -1).

Swetank Poddar
  • 1,257
  • 9
  • 23
  • 1
    Note that in order to iterate a ``range`` in reverse, ``reversed(range(len(myList))`` can be used. This will automatically calculate a new ``range`` with the proper bounds. – MisterMiyagi May 21 '20 at 10:32
  • If you are feeling more pythonic, you can also use `myList[::-1]`! :D – Swetank Poddar May 21 '20 at 10:33
  • Lists have an optimized reverse iterator as well, so ``reversed(myList)`` should be preferred. ``myList[::-1]`` creates an unnecessary copy. – MisterMiyagi May 21 '20 at 10:34
  • @MisterMiyagi: It doesn't really create a copy. Slicing usually copies the references to the objects and not the object it self... – Swetank Poddar May 21 '20 at 10:36
1

First of all know that indexes start from 0 and not 1. When you go for myList[6], first of all, it doesn't exist because index start from 0. If you have 6 elements, the the last index is 5. So, myList[5] is 'f'. Now, range() works such that when you give arguments as range(0, len(myList)), it iterates from 0 to len(myList)-1. It iterates upto 1 less than the given argument.

For your second question, again you will have to start with len(myList)-1 because last index is 5 in your case. And about where is a, you will have to go till range(len(myList)-1,-1,-1) so that it goes up till 0th index.

dewDevil
  • 381
  • 1
  • 3
  • 12
1

First question, why: python works that way, odd at firs but normal when you become used to it. Range[a, b] gives: a, a+1, a+2, ... b-1 (includes the first parameter and excludes the last).

It means that for the second question you should use:

for i in range(len(myList)-1, -1, -1):
    print(myList[i])
jlbmdm
  • 188
  • 6
1

Several things to note:

  1. Python is zero-indexed
    This explains the IndexError when executing myList[6] because the last element is #5 not #6.
  2. range(start, stop) is "front-inclusive" and "end-exclusive"
    So while iterating, you print myList[0] but not myList[6], which is why you did not get an IndexError here.
  3. range(n)
    n represents the number of times to execute the for loop, so because you would like to print 6 elements, you should do range(len(myList)) without -1.
  4. range(start, stop, step)
    Again, Python's for loops are "front-inclusive" and "end-exclusive" so you should start with the index of the last element (len(myList)-1) and end with the index of the first element minus 1 (-1). Step size can be thought of as the "displacement" while iterating, so with a step size of -1, you decrease the iterator i by one at each epoch.

Hope this helped!

ccl
  • 2,378
  • 2
  • 12
  • 26
  • Most of which is spelled out in the documentation [here](https://docs.python.org/3/library/stdtypes.html#typesseq-range) and [here](https://docs.python.org/3/library/stdtypes.html#typesseq). If one googles "python range" and looks for official sources, they'll instantly hit https://docs.python.org/3.8/library/functions.html#func-range which links to these docs. – Andras Deak -- Слава Україні May 21 '20 at 11:02