提问人:Joan Venge 提问时间:2/7/2009 最后编辑:cottontailJoan Venge 更新时间:8/26/2023 访问量:4249569
在“for”循环中访问索引
Accessing the index in 'for' loops
问:
如何在循环遍历序列时访问索引?for
xs = [8, 23, 45]
for x in xs:
print("item #{} = {}".format(index, x))
期望输出:
item #1 = 8
item #2 = 23
item #3 = 45
答:
for i in range(len(ints)):
print(i, ints[i]) # print updated to print() in Python 3.x+
评论
xrange
enumerate
i
老式方式:
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)
>>>
评论
使用内置函数 enumerate():
for idx, x in enumerate(xs):
print(idx, x)
通过手动索引或手动管理其他状态变量是非 pythonic 的。for i in range(len(xs)): x = xs[i]
查看 PEP 279 了解更多信息。
评论
enumerate
enumerate
range
enumerate
tuple
tuple
ssize_t
list
for i in range(5)
for i in range(len(ints))
enumerate
根据这个讨论:对象的列表索引
循环计数器迭代
当前用于循环索引的习惯使用内置函数: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
评论
从以下位置开始非常简单:1
0
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)
print
from __future__ import print_function
print
print
print(index, item)
index
tuple
使用 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'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])
使用 Enumerate 函数
Python 的枚举
函数通过隐藏索引的会计,并将可迭代对象封装到另一个可迭代对象(对象)中来减少视觉混乱,从而生成索引的两项元组和原始可迭代对象将提供的项。它看起来像这样:enumerate
for index, item in enumerate(items, start=0): # default is zero
print(index, item)
这个代码示例很好地说明了 Python 惯用代码和非 Python 代码之间差异的典型示例。惯用代码是复杂(但不复杂)的 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')
我们可以使用所谓的“序列解包”来从这个二元组中提取元素:
index, item = iteration
# 0, 'a' = (0, 'a') # essentially this.
当我们检查时,我们发现它指的是第一个索引 0,并引用了第一项。index
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 到 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
访问方法的索引和性能基准
在 Python 3.7 中访问循环中列表索引的最快方法是对小型、中型和大型列表使用 enumerate 方法。
请参阅下面的代码示例中可用于迭代列表和访问索引值及其性能指标的不同方法(我想这对您有用):
# 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
因此,当索引需要时,using method 是迭代速度最快的方法。enumerate
在下面添加一些有用的链接:
评论
按照 Python 中的惯例,有几种方法可以做到这一点。在所有示例中,假设:lst = [1, 2, 3, 4, 5]
- 使用 enumerate(被认为是最惯用的)
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
- 总有另一种方式
如前所述,还有其他方法可以做到这一点,这里没有解释,它们甚至可能在其他情况下更适用。例如,使用 for。它比其他示例更好地处理嵌套循环。itertools.chain
您也可以尝试以下操作:
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']
这很好地达到了目的:
list1 = [10, 'sumit', 43.21, 'kumar', '43', 'test', 3]
for x in list1:
print('index:', list1.index(x), 'value:', x)
评论
index()
x
要使用 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)]
您可以使用以下方法: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
它使用 in the selected answer to this question, but with list comprehension, make it faster with less code.enumerate
如果我要迭代,我会这样做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
在您的问题中,您写道“我如何访问循环索引,在本例中为 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
在 Python 3.12 上测试
这里有 12 个示例,说明如何使用 for 循环、while 循环和一些循环函数访问索引及其相应数组的元素。请注意,默认情况下,数组索引始终从零开始(请参阅更改此设置)。example 4
1.带有计数器和运算符的循环元素。+=
items = [8, 23, 45, 12, 78]
counter = 0
for value in items:
print(counter, value)
counter += 1
Result:
# 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)
Result:
# 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)
Result:
# 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. 您可以将该值更改为任何增量。index
items = [8, 23, 45, 12, 78]
for i, item in enumerate(items, start=100):
print(i, item)
Result:
# 100 8
# 101 23
# 102 45
# 103 12
# 104 78
5.使用方法自动计数器增量。range(len(...))
items = [8, 23, 45, 12, 78]
for i in range(len(items)):
print("Index:", i, "Value:", items[i])
Result:
# ('Index:', 0, 'Value:', 8)
# ('Index:', 1, 'Value:', 23)
# ('Index:', 2, 'Value:', 45)
# ('Index:', 3, 'Value:', 12)
# ('Index:', 4, 'Value:', 78)
6.使用loop inside功能。for
items = [8, 23, 45, 12, 78]
def enum(items, start=0):
counter = start
for value in items:
print(counter, value)
counter += 1
enum(items)
Result:
# 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
Result:
# 0 8
# 1 23
# 2 45
# 3 12
# 4 78
8. 返回 Generator 对象的语句。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)
Result:
# (0, 8)
# (1, 23)
# (2, 45)
# (3, 12)
# (4, 78)
9. 带有循环和 .for
lambda
items = [8, 23, 45, 12, 78]
xerox = lambda upperBound: [(i, items[i]) for i in range(0, upperBound)]
print(xerox(5))
Result:
# [(0, 8), (1, 23), (2, 45), (3, 12), (4, 78)]
10. 使用 Python 的函数一次遍历两个列表。zip()
items = [8, 23, 45, 12, 78]
indices = []
for index in range(len(items)):
indices.append(index)
for item, index in zip(items, indices):
print("{}: {}".format(index, item))
Result:
# 0: 8
# 1: 23
# 2: 45
# 3: 12
# 4: 78
11. 使用循环和 & 方法遍历 2 个列表。while
iter()
next()
items = [8, 23, 45, 12, 78]
indices = range(len(items))
iterator1 = iter(indices)
iterator2 = iter(items)
try:
while True:
i = next(iterator1)
element = next(iterator2)
print(i, element)
except StopIteration:
pass
Result:
# 0 8
# 1 23
# 2 45
# 3 12
# 4 78
12. 另外,在类中迭代列表的元素也很好。Static Method
items = [8, 23, 45, 12, 78]
class ElementPlus:
@staticmethod # decorator
def indexForEachOfMy(iterable):
for pair in enumerate(iterable):
print pair
ElementPlus.indexForEachOfMy(items)
Result:
# (0, 8)
# (1, 23)
# (2, 45)
# (3, 12)
# (4, 78)
评论
使用 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))
您可以在字符串文本中使用和嵌入表达式来获取解决方案。enumerate
这是一种简单的方法:
a=[4,5,6,8]
for b, val in enumerate(a):
print('item #{} = {}'.format(b+1, val))
一个循环,其中“counter”变量设置为初始值设定项,该初始值设定器将是一个参数,在格式化字符串时,作为项目编号。
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
可以通过以下代码实现:
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
您可以使用然后像这样查找索引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))
除了上面所有优秀的答案之外,这里还有在使用 pandas Series 对象时这个问题的解决方案。在许多情况下,pandas 系列具有无法使用函数访问的自定义/唯一索引(例如,唯一标识符字符串)。enumerate()
xs = pd.Series([8, 23, 45]) xs.index = ['G923002', 'G923004', 'G923005'] print(xs)
输出:
# G923002 8 # G923004 23 # G923005 45 # dtype: int64
我们可以在下面看到,这并没有给我们带来预期的结果:enumerate()
for id, x in enumerate(xs): print("id #{} = {}".format(id, x))
输出:
# id #0 = 8 # id #1 = 23 # id #2 = 45
我们可以在 for 循环中使用 pandas Series 的索引:.items()
for id, x in xs.items(): print("id #{} = {}".format(id, x))
输出:
# id #G923002 = 8 # id #G923004 = 23 # id #G923005 = 45
单行爱好者:
[index for index, datum in enumerate(data) if 'a' in datum]
说明:
>>> data = ['a','ab','bb','ba','alskdhkjl','hkjferht','lal']
>>> data
['a', 'ab', 'bb', 'ba', 'alskdhkjl', 'hkjferht', 'lal']
>>> [index for index, datum in enumerate(data) if 'a' in datum]
[0, 1, 3, 4, 6]
>>> [index for index, datum in enumerate(data) if 'b' in datum]
[1, 2, 3]
>>>
要点:
- Python 不提供索引;如果您正在使用
list
for
- 如果你一个,它会返回你另一个
enumerate
list
list
- 但是该列表将具有不同的类型
- 它将用索引包装每个元素
tuple
- 我们可以将元组作为变量访问,用逗号(
,
)
谢谢。求你让我在你们的祷告中。
在 for 循环中运行计数器的另一种方法是使用 .itertools.count
from itertools import count
my_list = ['a', 'b', 'a']
for i, item in zip(count(), my_list):
print(i, item)
这非常有用,尤其是当您希望计数器是小数时。在以下示例中,“索引”从 1.0 开始,并在每次迭代中递增 0.5。
my_list = ['a', 'b', 'a']
for i, item in zip(count(start=1., step=0.5), my_list):
print(f"loc={i}, item={item}")
# loc=1.0, item=a
# loc=1.5, item=b
# loc=2.0, item=a
另一种方法是在循环内使用。但是,与此页上提及此方法的其他答案(1、2、3)相反,索引搜索的起点(即第二个参数)必须传递给该方法。这可以让你实现两件事:(1)不会从头开始重复列表;(2)可以找到所有值的索引,甚至是重复的索引。list.index()
list.index()
my_list = ['a', 'b', 'a']
idx = -1
for item in my_list:
idx = my_list.index(item, idx+1)
# ^^^^^ <---- start the search from the next index
print(f"index={idx}, item={item}")
# index=0, item=a
# index=1, item=b
# index=2, item=a
在性能方面,如果您想要所有/大部分索引,是最快的选择。如果您只寻找特定的指数,那么可能会更有效。以下是两个更有效的例子。enumerate()
list.index()
list.index()
示例#1:特定值的索引
假设您要查找列表中出现特定值(例如最高值)的所有索引。例如,在以下示例中,我们希望查找出现 2 的所有索引。这是使用 .但是,我们也可以通过在 while 循环中使用该方法来搜索 2 的索引;如前所述,在每次迭代中,我们从上一次迭代中中断的位置开始索引搜索。enumerate()
list.index()
lst = [0, 2, 1, 2]
target = 2
result = []
pos = -1
while True:
try:
pos = lst.index(target, pos+1)
result.append(pos)
except ValueError:
break
print(result) # [1, 3]
事实上,在某些情况下,它比产生相同输出的选项要快得多,尤其是在列表很长的情况下。enumerate()
示例#2:小于目标的第一个数字的索引
在循环中经常需要索引的另一个常见练习是查找列表中满足某些条件(例如大于/小于某个目标值)的第一项的索引。在以下示例中,我们希望查找超过 2.5 的第一个值的索引。这是一个单行使用,但使用更有效,因为获取不会使用的索引是有成本的(不会产生)。enumerate()
list.index()
enumerate()
list.index()
my_list = [1, 2, 3, 4]
target = 2.5
for item in my_list:
if item > target:
idx = my_list.index(item)
break
或作为单行:
idx = next(my_list.index(item) for item in my_list if item > target)
用于生成运行时速度比图的代码:
import random
import matplotlib.pyplot as plt
import perfplot
def enumerate_1(lst, target=3):
return [i for i, v in enumerate(lst) if v == target]
def list_index_1(lst, target=3):
result = []
pos = -1
while True:
try:
pos = lst.index(target, pos+1)
result.append(pos)
except ValueError:
break
return result
def list_index_2(lst, target):
for item in lst:
if item > target:
return lst.index(item)
def enumerate_2(lst, target):
return next(i for i, item in enumerate(lst) if item > target)
setups = [lambda n: [random.randint(1, 10) for _ in range(n)],
lambda n: (list(range(n)), n-1.5)]
kernels_list = [[enumerate_1, list_index_1], [enumerate_2, list_index_2]]
titles = ['Get indices of a value', 'Get index that satisfies a condition']
n_range = [2**k for k in range(1,21)]
labels = ['enumerate', 'list.index']
xlabel = 'list length'
fig, axs = plt.subplots(1, 2, figsize=(10, 5), facecolor='white', dpi=60)
for i, (ax, su, ks, t) in enumerate(zip(axs, setups, kernels_list, titles)):
plt.sca(ax)
perfplot.plot(ks, n_range, su, None, labels, xlabel, t, relative_to=1)
ax.xaxis.set_tick_params(labelsize=13)
plt.setp(axs, ylim=(0.7, 2.4), yticks=[i*0.25 + 0.75 for i in range(7)],
xlim=(1, 1100000), xscale='log', xticks=[1, 100, 10000, 1000000])
fig.tight_layout();
评论