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.
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.