I want to loop through a list with a counter starting at zero but with the list starting index at 1 eg:
valueList = [1, 2, 3, 4]
secondList = ['a', 'b', 'c', 'd']
for i, item in enumerate(valueList, start=1):
print(secondList[i])
The code fails with an index out of range error (I realize this is because i ends at the length of the list -1 plus the start value and that python lists are zero indexed so using i in this way to call the ith element in another list is not valid). The following works but the addition of the test for i greater than zero looks un-pythonic.
valueList = [1, 2, 3, 4]
secondList = ['a', 'b', 'c', 'd']
for i, item in enumerate(valueList, start=0):
if i > 0:
print(secondList[i])
Enumerate is not the right choice, is there another way?
It sounds as if you want to slice the list instead; still start enumerate()
at one to get the same indices:
for i, item in enumerate(valueList[1:], start=1):
This then loops over valueList
starting at the second element, with matching indices:
>>> valueList = [1, 2, 3, 4]
>>> secondList = ['a', 'b', 'c', 'd']
>>> for i, item in enumerate(valueList[1:], start=1):
... print(secondList[i])
...
b
c
d
In this case, I'd just use zip()
instead, perhaps combined with itertools.islice()
:
from itertools import islice
for value, second in islice(zip(valueList, secondList), 1, None):
print(value, second)
The islice()
call skips the first element for you:
>>> from itertools import islice
>>> for value, second in islice(zip(valueList, secondList), 1, None):
... print(value, second)
...
2 b
3 c
4 d
The issue is not enumerate, and neither the start
argument, but the fact that when you do start=1
, you're enumerating from 1
to valueList+1
:
>>> valueList = [1, 2, 3, 4]
>>> secondList = ['a', 'b', 'c', 'd']
>>> for i, item in enumerate(valueList, start=1):
... print(i)
... print(secondList[i])
... print('----')
...
1
b
----
2
c
----
3
d
----
4
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
IndexError: list index out of range
So of course, when you try to access secondList[4]
there's no value available! You might want to do:
>>> for i, item in enumerate(valueList, start=1):
... if i < len(secondList):
... print(secondList[i])
...
b
c
d
That said, I'm not sure what you're exactly attempting to achieve. If you want to skip the first value of secondList
, that might be a solution, even though not the most efficient one. A better way would be to actually use the slice operator:
>>> print(secondList[1:])
['b', 'c', 'd']
If you want to iterate over a list using natural enumeration (instead of computer 's one), ie starting from 1
instead of 0
, then that's not the way to go. To show natural indexes and use computer indexes, you just have to do:
>>> for i, item in enumerate(valueList):
... print("{} {}".format(i+1, secondList[i]))
...
1 a
2 b
3 c
4 d
Finally, you could use zip()
instead of enumerate to link contents of both lists:
>>> for i, item in zip(valueList, secondList):
... print('{} {}'.format(i, item))
...
1 a
2 b
3 c
4 d
which will show each value of valueList
attached with the value of secondList
at the same index.
If your collections are generators, you might be best off doing:
for i, item in enumerate(valueList, start=1):
if i < 1:
continue
print(secondList[i])
or to modify Martijn Pieters's great answer,
from itertools import islice, izip
for value, second in islice(izip(valueList, secondList), 1, None):
print(value, second)
this way data are lazily loaded.
Or without using the start-parameter, you can do an if-comparison i > 0. That way you also don't have to deal with the list+1 index error at the end:
for i, item in enumerate(valueList):
if i > 0:
continue
print(secondList[i])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.