Search code examples
pythonpython-3.xlistenumerate

Python3: How the start parameter in enumerate function works?


I have a list. I want to deal with the items of the list from a variable starting point.

lines = ["line 0", ..., "line 25", ...]
cursor = 25

for i, line in enumerate(lines, start=cursor):
    print("cursor is at:", cursor)
    print("start line is:", lines[cursor])
    print("actual line is:", line)

Output:

cursor is at: 25
start line is: line 25
actual line is: line 0
...

I expect enumerate to start from cursor, but it starts at 0.


I'm sure that I misunderstood something, but I really want to understand how enumerate works to improve my Python.


Solution

  • Try to understand this simple example:

    lines = ['line 0', 'line 1', 'line 2']
    cursor = 4
    
    for idx, line in enumerate(lines, cursor):
        print(idx, '->', line)
    

    Output:

    4 -> line 0
    5 -> line 1
    6 -> line 2
    

    Observations:

    • idx starts from cursor (which is 4).
    • line starts from the beginning of lines, which is lines[0], and not from lines[4]. (If it started from lines[4], then it should have raised IndexError: list index out of range because the length of lines is just 3 and we can only access lines[0], ..., lines[2].)

    i.e. start parameter just affects idx and not line.


    We can use list slicing with enumerate to access items starting from cursor like this:

    lines = ['line 0', 'line 1', 'line 2', 'line 3', 'line 4', 'line 5', 'line 6']
    cursor = 4
    
    for idx, line in enumerate(lines[cursor:], cursor):    # Used slicing: lines[cursor:]
        print(idx, '->', line)
    

    Output:

    4 -> line 4
    5 -> line 5
    6 -> line 6
    

    But a disadvantage is that slicing creates a new list i.e. not memory efficient.


    An alternative is to use islice which does not create a new list i.e. memory efficient.

    from itertools import islice
    
    lines = ['line 0', 'line 1', 'line 2', 'line 3', 'line 4', 'line 5', 'line 6']
    cursor = 4
    
    for idx, line in enumerate(
        islice(lines, cursor, len(lines)),    # Used 'islice'
        cursor,
    ):
        print(idx, '->', line)
    

    Output:

    4 -> line 4
    5 -> line 5
    6 -> line 6
    

    Read more about islice in Python's Official Documentation.