访问 “for” 循环中的索引?

如何在如下所示的for循环中访问索引?

ints = [8, 23, 45, 12, 78]
for i in ints:
    print('item #{} = {}'.format(???, i))

我想得到这个输出:

item #1 = 8
item #2 = 23
item #3 = 45
item #4 = 12
item #5 = 78

当我使用for循环遍历它时,如何访问循环索引(在这种情况下为 1 到 5)?

答案

使用其他状态变量,例如索引变量(通常在 C 或 PHP 等语言中使用),被认为是非 Python 的。

更好的选择是使用内置函数enumerate() ,该函数在 Python 2 和 3 中都可用:

for idx, val in enumerate(ints):
    print(idx, val)

进一步了解PEP 279

使用 for 循环,在这种情况下如何访问循环索引(从 1 到 5)?

迭代时使用enumerate获取带有元素的索引:

for index, item in enumerate(items):
    print(index, item)

并请注意,Python 的索引从零开始,因此上述值将为 0 到 4。如果要计数 1 到 5,请执行以下操作:

for count, item in enumerate(items, start=1):
    print(count, item)

单项控制流

您所要求的是以下 Pythonic 等效项,这是大多数低级语言程序员将使用的算法:

index = 0            # Python's indexing starts at zero
for item in items:   # Python's for loops are a "for each" loop 
    print(index, item)
    index += 1

或使用没有 for-each 循环的语言:

index = 0
while index < len(items):
    print(index, items[index])
    index += 1

或有时在 Python 中更常见(但唯一):

for index in range(len(items)):
    print(index, items[index])

使用枚举功能

Python 的enumerate函数通过隐藏索引的记帐,并将可迭代项封装到另一个可迭代项(一个enumerate对象)中,从而减少了视觉混乱,该另一个可迭代项产生了索引和原始可迭代项将提供的项的两个项目元组。看起来像这样:

for index, item in enumerate(items, start=0):   # default is zero
    print(index, item)

此代码示例很好说明了 Python 特有的代码与非 Python 特有的代码之间的区别的典范示例。惯用代码是复杂的(但不复杂)Python,以预期使用的方式编写。语言的设计者期望使用惯用代码,这意味着通常该代码不仅更具可读性,而且效率更高。

计数

即使您不需要索引,但是您需要一个迭代计数(有时是理想的),您也可以从1开始,最后一个数字就是您的计数。

for count, item in enumerate(items, start=1):   # default is zero
    print(item)

print('there were {0} items printed'.format(count))

当您说想要从 1 到 5 时,该计数似乎更多地是您想要的内容(而不是索引)。


分解 - 逐步说明

为了分解这些示例,假设我们有一个要迭代的项目列表,并带有一个索引:

items = ['a', 'b', 'c', 'd', 'e']

现在,我们通过此可迭代的枚举,创建一个枚举对象:

enumerate_object = enumerate(items) # the enumerate object

我们可以从此迭代中提取第一项,以便与next函数循环进行:

iteration = next(enumerate_object) # first iteration from enumerate
print(iteration)

我们看到我们得到的元组为0 (第一个索引)和'a' (第一项):

(0, 'a')

我们可以使用所谓的 “ 序列拆包 ” 从这两个元组中提取元素:

index, item = iteration
#   0,  'a' = (0, 'a') # essentially this.

当我们检查index ,我们发现它指的是第一个索引 0,而item指的是第一个项'a'

>>> print(index)
0
>>> print(item)
a

结论

  • Python 索引从零开始
  • 要在迭代过程中从迭代器获取这些索引,请使用枚举函数
  • 以惯用方式使用枚举(以及元组拆包)将创建更易读和可维护的代码:

这样做:

for index, item in enumerate(items, start=0):   # Python indexes start at zero
    print(index, item)

0以外的其他1开始很简单:

for index, item in enumerate(iterable, start=1):
   print index, item

注意

重要提示,尽管有点误导,因为这里的index将是一个tuple (idx, item) 。好去。

for i in range(len(ints)):
   print i, ints[i]

按照 Python 的规范,有几种方法可以做到这一点。在所有示例中,假定: lst = [1, 2, 3, 4, 5]

1. 使用枚举( 被认为是最惯用的

for index, element in enumerate(lst):
    # do the things that need doing here

我认为这也是最安全的选择,因为消除了进行无限递归的机会。项目及其索引都保存在变量中,无需编写任何其他代码即可访问该项目。

2. 创建一个变量来保存索引( 使用for

for index in range(len(lst)):   # or xrange
    # you will have to write extra code to get the element

3. 创建一个变量来保存索引( 使用while

index = 0
while index < len(lst):
    # you will have to write extra code to get the element
    index += 1  # escape infinite recursion

4. 总有另一种方法

如前所述,还有其他方法尚未在此处进行说明,它们甚至可能在其他情况下更适用。 例如,itertools.chain与 for 一起使用。它比其他示例更好地处理嵌套循环。

老式的方式:

for ix in range(len(ints)):
    print ints[ix]

清单理解:

[ (ix, ints[ix]) for ix in range(len(ints))]

>>> ints
[1, 2, 3, 4, 5]
>>> for ix in range(len(ints)): print ints[ix]
... 
1
2
3
4
5
>>> [ (ix, ints[ix]) for ix in range(len(ints))]
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
>>> lc = [ (ix, ints[ix]) for ix in range(len(ints))]
>>> for tup in lc:
...     print tup
... 
(0, 1)
(1, 2)
(2, 3)
(3, 4)
(4, 5)
>>>

Python 2.7 中访问循环内列表索引的最快方法是对小列表使用range 方法 ,对中型和大型列表使用枚举方法

请在下面的代码示例中查看可用于遍历列表和访问索引值及其性能指标的 不同方法 (我认为这对您有用):

from timeit import timeit

# Using range
def range_loop(iterable):
    for i in range(len(iterable)):
        1 + iterable[i]

# Using xrange
def xrange_loop(iterable):
    for i in xrange(len(iterable)):
        1 + iterable[i]

# Using enumerate
def enumerate_loop(iterable):
    for i, val in enumerate(iterable):
        1 + val

# Manual indexing
def manual_indexing_loop(iterable):
    index = 0
    for item in iterable:
        1 + item
        index += 1

请参阅以下每种方法的性能指标:

from timeit import timeit

def measure(l, number=10000):
print "Measure speed for list with %d items" % len(l)
print "xrange: ", timeit(lambda :xrange_loop(l), number=number)
print "range: ", timeit(lambda :range_loop(l), number=number)
print "enumerate: ", timeit(lambda :enumerate_loop(l), number=number)
print "manual_indexing: ", timeit(lambda :manual_indexing_loop(l), number=number)

measure(range(1000))
# Measure speed for list with 1000 items
# xrange:  0.758321046829
# range:  0.701184988022
# enumerate:  0.724966049194
# manual_indexing:  0.894635915756

measure(range(10000))
# Measure speed for list with 100000 items
# xrange:  81.4756360054
# range:  75.0172479153
# enumerate:  74.687623024
# manual_indexing:  91.6308541298

measure(range(10000000), number=100)
# Measure speed for list with 10000000 items
# xrange:  82.267786026
# range:  84.0493988991
# enumerate:  78.0344707966
# manual_indexing:  95.0491430759

结果,使用range方法是列出 1000 个项目中最快的方法。对于大小大于 10000 的列表,则enumerate为获胜者。

在下面添加一些有用的链接:

首先,索引将从 0 到 4。编程语言从 0 开始计数;从 0 开始计数。不要忘了,否则您将遇到索引超出范围的异常。 for 循环中需要的只是一个从 0 到 4 的变量,如下所示:

for x in range(0, 5):

请记住,我写了 0 到 5,因为循环在最大值之前停了一个数字。 :)

要获取索引的值,请使用

list[index]

根据此讨论: http : //bytes.com/topic/python/answers/464012-objects-list-index

循环计数器迭代

当前用于遍历索引的习惯用法使用内置的range函数:

for i in range(len(sequence)):
    # work with index i

可以通过旧习惯用法或使用新的zip内置函数来实现元素和索引上的循环:

for i in range(len(sequence)):
    e = sequence[i]
    # work with index i and element e

要么

for i, e in zip(range(len(sequence)), sequence):
    # work with index i and element e

通过http://www.python.org/dev/peps/pep-0212/

您可以使用以下代码进行操作:

ints = [8, 23, 45, 12, 78]
index = 0

for value in (ints):
    index +=1
    print index, value

如果您需要在循环结束时重置索引值,请使用此代码:

ints = [8, 23, 45, 12, 78]
index = 0

for value in (ints):
    index +=1
    print index, value
    if index >= len(ints)-1:
        index = 0