使用内置函数 enumerate()
:
for idx, x in enumerate(xs):
print(idx, x)
non-pythonic 通过 for i in range(len(xs)): x = xs[i]
手动索引或手动管理附加状态变量。
查看PEP 279了解更多信息。
使用 for 循环,我如何访问循环索引,在这种情况下从 1 到 5?
在迭代时使用 enumerate
获取元素的索引:
for index, item in enumerate(items):
print(index, item)
请注意,Python 的索引从零开始,所以你会得到 0 到 4 上面。如果您想要计数,从 1 到 5,请执行以下操作:
count = 0 # in case items is empty and you need it after the loop
for count, item in enumerate(items, start=1):
print(count, item)
统一的控制流
您要求的是以下 Pythonic 等价物,这是大多数低级语言程序员会使用的算法:
index = 0 # Python 的索引从零开始 for item in items: # Python 的 for 循环是一个“for each”循环 print(index, item) index += 1
或者在没有 for-each 循环的语言中:
index = 0 而 index < len(items): print(index, items[index]) index += 1
或者有时在 Python 中更常见(但不习惯):
对于范围内的索引(len(items)):打印(索引,项目[索引])
使用枚举函数
Python 的 enumerate
function 通过隐藏索引的说明来减少视觉上的混乱,并将可迭代对象封装到另一个可迭代对象(enumerate
对象)中,从而生成索引的两项元组和原始可迭代对象将提供的项。看起来像这样:
for index, item in enumerate(items, start=0): # default is zero
print(index, item)
此代码示例很好地说明了 Python 惯用代码与非 Python 惯用代码之间的差异canonical示例。惯用代码是复杂(但不复杂)的 Python,以预期使用的方式编写。该语言的设计者期望使用惯用代码,这意味着通常该代码不仅更具可读性,而且更高效。
计数
即使您不需要索引,但您需要计算迭代次数(有时是可取的),您可以从 1
开始,最终数字将是您的计数。
count = 0 # in case items is empty
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')
我们可以使用所谓的“sequence unpacking”从这个二元组中提取元素:
index, item = iteration
# 0, 'a' = (0, 'a') # essentially this.
当我们检查 index
时,我们发现它指的是第一个索引 0,而 item
指的是第一个项目 'a'
。
>>> print(index)
0
>>> print(item)
a
结论
Python 索引从零开始
要在迭代时从可迭代对象中获取这些索引,请使用 enumerate 函数
以惯用的方式使用 enumerate(以及元组解包)创建的代码更具可读性和可维护性:
所以这样做:
for index, item in enumerate(items, start=0): # Python indexes start at zero
print(index, item)
items
为空时,“获取计数”示例是否有效?
count = 0
以确保它具有值(当循环从未分配给 count
时,它是正确的值,因为根据定义没有项目)。
从 0
以外的 1
开始非常简单:
for index, item in enumerate(iterable, start=1):
print index, item # Used to print in python<3.x
print(index, item) # Migrate to print() after 3.x+
index, item
的元组变量称为 index
是非常具有误导性的。只需使用 for index, item in enumerate(ints)
。
index
变成 (index)
不会改变 Py2 或 Py3 上的任何事情。我觉得您可能正在考虑更改为 print
;在 Py2 和 Py3 上实现该功能的唯一方法是将 from __future__ import print_function
添加到文件顶部以获得一致的 Py3 样式 print
,并将 print
更改为 print(index, item)
。或者,当 index
是原始 tuple
时,您阅读了问题的早期编辑,未解压缩为两个名称,但如果您未能解压缩,括号仍然不会改变任何内容。
for i in range(len(ints)):
print(i, ints[i]) # print updated to print() in Python 3.x+
xrange
。
enumerate
如何保存任何逻辑;您仍然必须选择要使用 i
索引的对象,不是吗?
正如 Python 中的规范一样,有几种方法可以做到这一点。在所有示例中假设:lst = [1, 2, 3, 4, 5]
使用枚举(被认为是最惯用的)
for index, element in enumerate(lst):
# Do the things that need doing here
在我看来,这也是最安全的选择,因为已经消除了进入无限递归的机会。项目及其索引都保存在变量中,无需编写任何进一步的代码来访问该项目。
创建一个变量来保存索引(使用for)
for index in range(len(lst)): # or xrange
# you will have to write extra code to get the element
创建一个变量来保存索引(使用while)
index = 0
while index < len(lst):
# You will have to write extra code to get the element
index += 1 # escape infinite recursion
总有另一种方式
如前所述,还有其他方法可以做到这一点,这里没有解释,它们甚至可能更适用于其他情况。 例如,将 itertools.chain
与 for 一起使用。它比其他示例更好地处理嵌套循环。
以下是使用 for-in 循环访问索引和数组元素的方法。
1. 使用计数器和 += 运算符循环元素。
items = [8, 23, 45, 12, 78]
counter = 0
for value in items:
print(counter, value)
counter += 1
结果:
# 0 8
# 1 23
# 2 45
# 3 12
# 4 78
2. 使用 enumerate() 方法循环元素。
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)
3. 分别使用索引和值。
items = [8, 23, 45, 12, 78]
for index, value in enumerate(items):
print("index", index, "for value", value)
结果:
# 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
4.您可以将索引号更改为任何增量。
items = [8, 23, 45, 12, 78]
for i, value in enumerate(items, start=1000):
print(i, value)
结果:
# 1000 8
# 1001 23
# 1002 45
# 1003 12
# 1004 78
5. 使用 range(len(...)) 自动增加计数器。
items = [8, 23, 45, 12, 78]
for i in range(len(items)):
print("Index:", i, "Value:", items[i])
结果:
# ('Index:', 0, 'Value:', 8)
# ('Index:', 1, 'Value:', 23)
# ('Index:', 2, 'Value:', 45)
# ('Index:', 3, 'Value:', 12)
# ('Index:', 4, 'Value:', 78)
6.在函数内部使用for-in循环。
items = [8, 23, 45, 12, 78]
def enum(items, start=0):
counter = start
for value in items:
print(counter, value)
counter += 1
enum(items)
结果:
# 0 8
# 1 23
# 2 45
# 3 12
# 4 78
7. 当然,我们不能忘记while循环。
items = [8, 23, 45, 12, 78]
counter = 0
while counter < len(items):
print(counter, items[counter])
counter += 1
结果:
# 0 8
# 1 23
# 2 45
# 3 12
# 4 78
8. yield 语句返回一个生成器对象。
def createGenerator():
items = [8, 23, 45, 12, 78]
for (j, k) in enumerate(items):
yield (j, k)
generator = createGenerator()
for i in generator:
print(i)
结果:
# (0, 8)
# (1, 23)
# (2, 45)
# (3, 12)
# (4, 78)
9. 带有 for-in 循环和 lambda 的内联表达式。
items = [8, 23, 45, 12, 78]
xerox = lambda upperBound: [(i, items[i]) for i in range(0, upperBound)]
print(xerox(5))
结果:
# [(0, 8), (1, 23), (2, 45), (3, 12), (4, 78)]
老套路:
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 3.7 中访问循环内列表索引的最快方法是将 enumerate method 用于小型、中型和大型列表。
请在下面的代码示例中查看可用于迭代列表和访问索引值及其性能指标(我认为这对您有用)的不同方法:
# 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
方法是最快的迭代方法。
在下面添加一些有用的链接:
Python 2.X 中的 range 和 xrange 函数有什么区别?
在 Python 中使用 enumerate 的 for 循环或使用 xrange 的 for 循环哪个更快?
范围(len(list))还是枚举(list)?
您可以使用 enumerate
并在字符串文字中嵌入表达式来获得解决方案。
这是一个简单的方法:
a=[4,5,6,8]
for b, val in enumerate(a):
print('item #{} = {}'.format(b+1, val))
首先,索引将从 0 到 4。编程语言从 0 开始计数;不要忘记这一点,否则您将遇到索引越界异常。在 for 循环中,您只需要一个从 0 计数到 4 的变量,如下所示:
for x in range(0, 5):
请记住,我写了 0 到 5,因为循环在最大值之前停止了一个数字。 :)
要获取索引的值,请使用
list[index]
您可以使用以下代码执行此操作:
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
根据这个讨论:object's 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
通过 PEP 212 – Loop Counter Iteration。
在您的问题中,您写道“我如何访问循环索引,在这种情况下从 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
这将我们带到 enumerate()
的 start=n
开关。这只是抵消了索引,您可以等效地简单地在循环内的索引中添加一个数字。
for n, a in enumerate(alist, start=1):
print("%d %d" % (n, a))
输出为
1 1
2 2
3 3
4 4
5 5
如果我要迭代 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])
如果列表中没有重复值:
for i in ints:
indx = ints.index(i)
print(i, indx)
enumerate
长 1000 倍。你应该删除这个答案。
你也可以试试这个:
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']
您可以使用 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
的方法,但具有列表理解,从而以更少的代码使其更快。
使用 while 循环的简单答案:
arr = [8, 23, 45, 12, 78]
i = 0
while i < len(arr):
print("Item ", i + 1, " = ", arr[i])
i += 1
输出:
Item 1 = 8
Item 2 = 23
Item 3 = 45
Item 4 = 12
Item 5 = 78
您可以简单地使用诸如 count
的变量来计算列表中的元素数量:
ints = [8, 23, 45, 12, 78]
count = 0
for i in ints:
count = count + 1
print('item #{} = {}'.format(count, i))
要使用 for 循环在列表推导中打印 (index, value) 元组:
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)]
您可以使用 range(len(some_list))
然后像这样查找索引
xs = [8, 23, 45]
for i in range(len(xs)):
print("item #{} = {}".format(i + 1, xs[i]))
或者使用 Python 的内置 enumerate
函数,该函数允许您遍历列表并检索列表中每个项目的索引和值
xs = [8, 23, 45]
for idx, val in enumerate(xs, start=1):
print("item #{} = {}".format(idx, val))
可以通过以下代码实现:
xs = [8, 23, 45]
for x, n in zip(xs, range(1, len(xs)+1)):
print("item #{} = {}".format(n, x))
这里,range(1, len(xs)+1);如果您希望输出从 1 而不是 0 开始,则需要从 1 开始范围并将 1 添加到估计的总长度,因为默认情况下 python 从 0 开始索引数字。
Final Output:
item #1 = 8
item #2 = 23
item #3 = 45
将“计数器”变量设置为初始化程序的循环,该变量将作为参数,在格式化字符串时作为项目编号。
for 循环访问作为列表的“listos”变量。当我们通过“i”访问列表时,“i”被格式化为商品价格(或任何价格)。
listos = [8, 23, 45, 12, 78]
counter = 1
for i in listos:
print('Item #{} = {}'.format(counter, i))
counter += 1
输出:
Item #1 = 8
Item #2 = 23
Item #3 = 45
Item #4 = 12
Item #5 = 78
counter += 1
与 for
循环在同一级别缩进。在这种情况下,它会在 for
循环的每次迭代中更新。在这里,它在 while
循环的每次迭代中更新。我对 while
循环的问题仍然存在:当计数器可以在 for
循环中更新时,为什么需要使用 while 循环?这在 Rahul's answer 中显而易见。
这很好地达到了目的:
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 )查找每个元素所需的时间。
不定期副业成功案例分享
enumerate
不会产生其他开销吗?enumerate
。range
和索引的开销,也低于单独手动跟踪和更新索引的开销。带解包的enumerate
进行了高度优化(如果将tuple
解包为提供的示例中的名称,它会在每个循环中重用相同的tuple
以避免甚至空闲列表查找的成本,它具有优化的代码路径当索引适合执行廉价的寄存器内数学运算的ssize_t
时,绕过 Python 级别的数学运算,并且它避免在 Python 级别索引list
,这比您想象的要昂贵)。for i in range(5)
或for i in range(len(ints))
将执行迭代索引的普遍常见操作。但是,如果您希望项目 和 都是索引,则enumerate
是一个 非常 有用的语法。我用它所有的时间。