简体   繁体   English

Python枚举列表设置开始索引但不增加结束计数

[英]Python enumerate list setting start index but without increasing end count

I want to loop through a list with a counter starting at zero but with the list starting index at 1 eg:我想遍历一个列表,计数器从零开始,但列表的起始索引为 1,例如:

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).代码因索引超出范围错误而失败(我意识到这是因为我以列表的长度 -1 加上起始值结束,并且 Python 列表的索引为零,因此以这种方式使用 i 来调用另一个中的第 i 个元素列表无效)。 The following works but the addition of the test for i greater than zero looks un-pythonic.下面的工作,但对 i 大于零的测试的添加看起来不是 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:仍然从一开始enumerate()以获得相同的索引:

for i, item in enumerate(valueList[1:], start=1):

This then loops over valueList starting at the second element, with matching indices:然后从第二个元素开始循环遍历valueList ,并使用匹配的索引:

>>> 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() :在这种情况下,我只使用zip()代替,也许结合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: islice()调用会为您跳过第一个元素:

>>> 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 :问题不是枚举,也不是start参数,而是当您执行start=1 ,您是从1枚举到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!所以当然,当您尝试访问secondList[4] ,没有可用的值! 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.如果您想跳过secondList的第一个值,这可能是一个解决方案,即使不是最有效的解决方案。 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.如果您想使用自然枚举(而不是计算机的枚举)迭代列表,即从1而不是0 ,那么这不是要走的路。 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:最后,您可以使用zip()而不是 enumerate 来链接两个列表的内容:

>>> 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.这将显示valueList每个值与相同索引处的secondList的值。

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,或者修改 Martijn Pieters 的好答案,

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:或者不使用 start-parameter,你可以做一个 if-comparison i > 0。这样你也不必在最后处理 list+1 索引错误:

for i, item in enumerate(valueList):
    if i > 0:
        continue
    print(secondList[i])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM