Search code examples
pythonloopsfor-looptypeerrorindex-error

TypeError/IndexError when iterating with a for loop, and referencing lst[i]


I'm using a for loop to iterate over a list like this:

lst = ['a', 'b', 'c']
for i in lst:
    print(lst[i])

But there must be something wrong with that, because it throws the following exception:

Traceback (most recent call last):
  File "untitled.py", line 3, in <module>
    print(lst[i])
TypeError: list indices must be integers or slices, not str

And if I try the same thing with a list of integers, it throws an IndexError instead:

lst = [5, 6, 7]
for i in lst:
    print(lst[i])
Traceback (most recent call last):
  File "untitled.py", line 4, in <module>
    print(lst[i])
IndexError: list index out of range

What's wrong with my for loop?


Solution

  • Python's for loop iterates over the values of the list, not the indices:

    lst = ['a', 'b', 'c']
    for i in lst:
        print(i)
    
    # output:
    # a
    # b
    # c
    

    That's why you get an error if you try to index lst with i:

    >>> lst['a']
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: list indices must be integers or slices, not str
    
    >>> lst[5]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IndexError: list index out of range
    

    Many people use indices to iterate out of habit, because they're used to doing it that way from other programming languages. In Python you rarely need indices. Looping over the values is much more convenient and readable:

    lst = ['a', 'b', 'c']
    for val in lst:
        print(val)
    
    # output:
    # a
    # b
    # c
    

    And if you really need the indices in your loop, you can use the enumerate function:

    lst = ['a', 'b', 'c']
    for i, val in enumerate(lst):
        print('element {} = {}'.format(i, val))
    
    # output:
    # element 0 = a
    # element 1 = b
    # element 2 = c