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


3599

如何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)?


42
请注意,python中的索引从0开始,因此示例列表的索引是0到4而不是1到5
–plugwash

Answers:


6105

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

更好的选择是使用enumerate()Python 2和3中都提供的内置函数。

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

进一步了解PEP 279


61
正如亚伦指出的那样,如果您想获得1-5而不是0-4,请使用start = 1。
clozach

2
难道enumerate不会产生其他开销?
TheRealChx101 '19

根据我的测试(Python 3.6.3),@ TheRealChx101的差异可以忽略不计,有时甚至支持enumerate
Błotosmętek

803

使用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)

1
空时“ 计数 ”示例可以工作items吗?
Bergi

我正在使用ajax将数据作为数组以变量legData中值为2的两个值的形式发送到Django视图[1406, 1409]。如果我使用打印到控制台print(legData),则输出为[1406,1409]。但是,如果我尝试解析list的单个值,例如for idx, xLeg in enumerate(legData): print(idx, xLeg),它会为我输出单个整数,例如[,1,4,0,6,依此类推,以索引0,1,2,3,4等。(是的,也输出方括号和逗号,就像它们是数据本身的一部分一样)。这是怎么了?
user12379095

@ user12379095您可能使用了错误类型(字符串)的数据,并且需要将其转换为实际的数字列表,而不是字符串。这在这里有点偏离主题,请删除您的评论,并在看到此标志时将其标记为不再需要。
亚伦·霍尔

151

这是很简单的,从开始它1以外0

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

注意

重要提示,尽管index可能会引起误解,但tuple (idx, item)在这里。好去。


10
问题是关于列表索引。因为它们从0开始,所以从其他数字开始几乎没有意义,因为索引将是错误的(是的,OP在问题中也说错了)。否则,调用变量是元组index, item仅仅index是非常误导,正如你指出。只需使用for index, item in enumerate(ints)
Antti Haapala

1
更好的方法是将括号对内的索引括为(index),它将同时适用于Python版本2和
3。– hygull

1
@AnttiHaapala我认为,原因是问题的预期输出始于索引1而不是0
pushkin

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

10
那可能是xrange3.0之前的版本。
本·布兰克

42
请改用枚举
saulspatz

3
对于上面的Python 2.3,请使用枚举内置函数,因为它更具Pythonic功能。
januarvs

枚举并不总是更好-它取决于应用程序的要求。在当前情况下,对象长度之间的关系对我的应用程序有意义。尽管我一开始使用枚举,但为了避免不得不编写逻辑来选择要枚举的对象,我切换到了这种方法。
adg

1
@adg我看不到避免如何enumerate节省任何逻辑;您仍然必须选择要索引的对象i,不是吗?
chepner

47

按照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.chainfor。它比其他示例更好地处理嵌套循环。


30

老式的方式:

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

3
这是不是错误的,在C / C ++和其他人使用。它被认为是非pythonic的,但也可以在python中使用。就像将其分解为源的简单解决方案一样:+
Valor Naram

一些python 极端主义者会说,不要这样做。但我说的仅是表明,有不止一种可能的方式
Valor Naram

21

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则为获胜者。

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


5
“可读性计数” <1000的小范围内的速度差异不明显。在已经很小的时间指标上,速度要慢3%。

如何更新Python 3的答案?
乔治,

14

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

for x in range(0, 5):

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

要获取索引的值,请使用

list[index]

13

这是for循环访问索引时得到的结果:

for i in enumerate(items): print(i)

items = [8, 23, 45, 12, 78]

for i in enumerate(items):
    print("index/value", i)

结果:

# index/value (0, 8)
# index/value (1, 23)
# index/value (2, 45)
# index/value (3, 12)
# index/value (4, 78)

for i, val in enumerate(items): print(i, val)

items = [8, 23, 45, 12, 78]

for i, val in enumerate(items):
    print("index", i, "for value", val)

结果:

# index 0 for value 8
# index 1 for value 23
# index 2 for value 45
# index 3 for value 12
# index 4 for value 78

for i, val in enumerate(items): print(i)

items = [8, 23, 45, 12, 78]

for i, val in enumerate(items):
    print("index", i)

结果:

# index 0
# index 1
# index 2
# index 3
# index 4

12

根据此讨论: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/


22
这对于遍历生成器不起作用。只需使用enumerate()。
塔德克

如今,当前的习惯用法是枚举,而不是范围调用。
TankorSmash


11

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

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

10

解决此问题的最佳方法是使用枚举内置python函数。
枚举返回元组
第一个值是索引,
第二个值是该索引处数组的元素

In [1]: ints = [8, 23, 45, 12, 78]

In [2]: for idx, val in enumerate(ints):
   ...:         print(idx, val)
   ...:     
(0, 8)
(1, 23)
(2, 45)
(3, 12)
(4, 78)

9

在您的问题中,您写道:“在这种情况下,我如何从1到5访问循环索引?”

但是,列表的索引从零开始。因此,那么我们需要知道您真正想要的是列表中每个项目的索引和项目,还是您真正想要的是从1开始的数字。幸运的是,在Python中,执行这一项或两项都很容易。

首先,要澄清一下,该enumerate函数迭代地返回列表中每个项目的索引和相应项目。

alist = [1, 2, 3, 4, 5]

for n, a in enumerate(alist):
    print("%d %d" % (n, a))

上面的输出是

0 1
1 2
2 3
3 4
4 5

请注意,索引从0开始。这种索引在包括Python和C在内的现代编程语言中很常见。

如果希望循环跨越列表的一部分,则可以将标准Python语法用于列表的一部分。例如,要从列表中的第二个项目循环到最后一个但不包括最后一个项目,可以使用

for n, a in enumerate(alist[1:-1]):
    print("%d %d" % (n, a))

请再次注意,输出索引从0开始,

0 2
1 3
2 4

这给我们带来了start=n的开关enumerate()。这只是使索引偏移,您可以等效地在循环内向索引简单地添加一个数字。

for n, a in enumerate(alist, start=1):
    print("%d %d" % (n, a))

其输出是

1 1
2 2
3 3
4 4
5 5


7

如果列表中没有重复的值:

for i in ints:
    indx = ints.index(i)
    print(i, indx)

1
请注意,不应使用第一个选项,因为仅当序列中的每个项目都是唯一的时,它才可以正常工作。
斯坦凯

2
第一个选择是O(n²),这是一个糟糕的主意。如果您的列表长度为1000个元素,则实际上要比使用花费1000倍的时间enumerate。您应该删除此答案。
鲍里斯(Boris)

5

您也可以尝试以下操作:

data = ['itemA.ABC', 'itemB.defg', 'itemC.drug', 'itemD.ashok']
x = []
for (i, item) in enumerate(data):
      a = (i, str(item).split('.'))
      x.append(a)
for index, value in x:
     print(index, value)

输出是

0 ['itemA', 'ABC']
1 ['itemB', 'defg']
2 ['itemC', 'drug']
3 ['itemD', 'ashok']

3

您可以使用index方法

ints = [8, 23, 45, 12, 78]
inds = [ints.index(i) for i in ints]

编辑 在注释中突出显示,如果中存在重复项ints,则此方法不起作用,下面的方法应适用于以下任何值ints

ints = [8, 8, 8, 23, 45, 12, 78]
inds = [tup[0] for tup in enumerate(ints)]

或者

ints = [8, 8, 8, 23, 45, 12, 78]
inds = [tup for tup in enumerate(ints)]

如果要同时获取索引和值ints作为元组列表。

它使用在enumerate此问题的选定答案中的方法,但具有列表理解功能,因此可以用较少的代码来加快速度。



1

要使用for循环在列表理解中打印(索引,值)的元组:

ints = [8, 23, 45, 12, 78]
print [(i,ints[i]) for i in range(len(ints))]

输出:

[(0, 8), (1, 23), (2, 45), (3, 12), (4, 78)]

1

这足以达到目的:

list1 = [10, 'sumit', 43.21, 'kumar', '43', 'test', 3]
for x in list1:
    print('index:', list1.index(x), 'value:', x)

4
如果列表中有重复的元素,则此方法将失效,因为index()它将搜索第一次出现的x,而不提及查找每个元素所需的O(n ^ 2)时间。
Peter Szoldan '18

完全同意,它不适用于列表中的重复元素。毕竟我也在学习python。
Sumit Kumar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.