如何在如下所示的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)? />

评论

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

#1 楼

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

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

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


请查看PEP 279了解更多信息。

评论


正如亚伦(Aaron)指出的那样,如果要获得1-5而不是0-4,请使用start = 1。

– clozach
18年3月31日在22:16

枚举不会引起其他开销吗?

–TheRealChx101
19-10-17在23:03

根据我的测试(Python 3.6.3),@ TheRealChx101的差异可以忽略不计,有时甚至支持枚举。

–Błotosmętek
2月7日12:18

@ TheRealChx101:低于循环遍历一个范围并每次进行索引的开销,也低于分别手动跟踪和更新索引的开销。使用解压缩枚举进行了优化(如果将元组解压缩为所提供的示例中的名称,则它在每个循环中重用相同的元组,甚至避免了自由列表查找的开销,当索引适合ssize_t时,它具有优化的代码路径)执行便宜的寄存器内数学运算,而绕过Python级别的数学运算,并且避免在Python级别建立索引列表,这比您想象的要昂贵。

–ShadowRanger
10月6日18:19

#2 楼


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


Unidiomatic控制流

您要的是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索引从零开始
要在迭代过程中从迭代器中获取这些索引,请使用枚举函数
以惯用方式使用枚举(al并使用元组解包)创建的代码更具可读性和可维护性:

这样做:

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


评论


物品为空时,“获取计数”示例是否起作用?

–贝尔吉
2月22日15:36

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

–user12379095
5月15日15:51



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

–亚伦·霍尔♦
5月15日23:01

@Bergi:不会,但是您可以在循环之前添加count = 0以确保它具有值(并且在循环从不分配计数时是正确的值,因为根据定义,没有项目)。

–ShadowRanger
10月6日18:21

#3 楼

1之外的0开始非常简单:
for index, item in enumerate(iterable, start=1):
   print index, item


评论


问题是关于列表索引。因为它们从0开始,所以从其他数字开始几乎没有意义,因为索引将是错误的(是的,OP在问题中也说错了)。否则,正如您所指出的那样,调用索引为index元组的变量,而item just index是非常误导的。仅用于索引,枚举(ints)中的项目。

–安蒂·哈帕拉(Antti Haapala)
16-3-18在9:18



更好的方法是将括号对内的索引括为(index),它将在Python版本2和3上均适用。

–海鸥
18年1月2日,11:31

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

–普希金
18年11月30日在18:24

@hygull:将索引转换为(index)不会更改Py2或Py3上的任何内容。我觉得您可能正在考虑更改印刷版;使其在Py2和Py3上都能正常工作的唯一方法是从__future__ import print_function添加到文件顶部以获得一致的Py3样式的打印,然后将打印更改为print(索引,项目)。或者,当index是原始元组而不是解包为两个名称时,您阅读了对该问题的较早版本,但是如果您无法解包,括号仍然不会改变任何内容。

–ShadowRanger
10月6日18:23



#4 楼

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


评论


对于3.0之前的版本,可能应该是xrange。

–本空白
09年2月6日在22:52

使用枚举代替

– saulspatz
15年8月1日在21:28

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

– januarvs
17 Mar 15 '17 at 6:31

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

–adg
17年3月31日在23:18

@adg我看不到避免枚举如何保存任何逻辑;您仍然必须选择要用i索引的对象,不是吗?

–chepner
17年9月15日在23:15

#5 楼

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

#6 楼

老式的方法:

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


评论


这没错,并且在C / C ++和其他语言中使用。它被认为是非pythonic的,但也可以在python中使用。就像将其分解为源代码的简单解决方案一样:+

– Valor Naram
18年7月29日在20:57

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

– Valor Naram
18年7月30日在13:51

#7 楼

访问索引和方法的性能基准测试
在Python 3.7中访问循环内列表索引的最快方法是对小型,中型和大型列表使用枚举方法。
请参阅可以使用的不同方法在下面的代码示例中遍历列表和访问索引值及其性能指标(我认为这对您有用):
# Using range
def range_loop(iterable):
    for i in range(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("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 speed for list with 1000 items
measure(range(1000))
# range:  1.161622366
# enumerate:  0.5661940879999996
# manual_indexing:  0.610455682

# Measure speed for list with 100000 items
measure(range(10000))
# range:  11.794482958
# enumerate:  6.197628574000001
# manual_indexing:  6.935181098000001

# Measure speed for list with 10000000 items
measure(range(10000000), number=100)
# range:  121.416859069
# enumerate:  62.718909123
# manual_indexing:  69.59575057400002

结果,使用enumerate方法是需要索引时最快的迭代方法。
在下面添加一些有用的链接:


range和之间有什么区别? Python 2.X中的xrange函数?


在Python中使用枚举进行循环或使用xrange进行循环的速度更快?


range(len (列表))还是枚举(列表)?



评论


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

–user4805123
17 Mar 4 '17 at 0:08

如何更新Python 3的答案?

–乔治
19年5月22日在14:20

@Georgy很有道理,在python 3.7上枚举是总赢家:)

– Andriy Ivaneyko
6月16日9:22

#8 楼

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

for x in range(0, 5):


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

要获取索引的值,请使用

list[index]


#9 楼

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


#10 楼

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

评论


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

–塔德克
13年3月31日在18:24

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

–TankorSmash
16年8月15日在18:12

它与较早的答案相同:stackoverflow.com/a/522576/6451573

–Jean-FrançoisFabre♦
19年4月20日在12:54

#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


#12 楼

解决此问题的最佳方法是使用枚举内置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)


#13 楼

如果要迭代nums = [1, 2, 3, 4, 5],我会做

for i, num in enumerate(nums, start=1):
    print(i, num)


,或者将长度取为l = len(nums)

for i in range(l):
    print(i+1, nums[i])


#14 楼

在您的问题中,您写道:“在这种情况下,我如何访问循环索引,从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=nenumerate()开关。这只是偏移索引,您可以等效地在循环内部简单地在索引中添加一个数字。

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


输出的结果是
 1 1
2 2
3 3
4 4
5 5
 


#15 楼

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

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


评论


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

– Stam Kaly
18/12/19在14:05

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

–鲍里斯(Boris)
19年4月20日在10:24

#16 楼

您也可以尝试以下方法:

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']


#17 楼

您可以使用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的方法,但是具有列表理解功能,因此用更少的代码就能更快地实现。

#18 楼

使用While循环的简单答案:
arr = [8, 23, 45, 12, 78]
i = 0
while i < len(arr):
    print("Item ", i + 1, " = ", arr[i])
    i += 1

输出:


#19 楼

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


#20 楼

这足以满足以下目的:

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


评论


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

– Peter Szoldan
18年5月15日在17:17

完全同意,它不适用于列表中的重复元素。毕竟我也在学习python。

– Sumit Kumar
18年6月6日在10:16