繁体   English   中英

在“for”循环中访问索引

[英]Accessing the index in 'for' loops

如何在使用for循环迭代序列时访问索引?

xs = [8, 23, 45]

for x in xs:
    print("item #{} = {}".format(index, x))

所需的 output:

item #1 = 8
item #2 = 23
item #3 = 45

使用内置函数enumerate()

for idx, x in enumerate(xs):
    print(idx, x)

通过for i in range(len(xs)): x = xs[i]手动索引或手动管理其他状态变量是非 Pythonic

查看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'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开始,最终数字将是您的计数。

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.

当我们检查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)

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+
   
for i in range(len(ints)):
   print(i, ints[i]) # print updated to print() in Python 3.x+ 

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

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

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

在我看来,这也是最安全的选择,因为已经消除了进入无限递归的机会。 项目及其索引都保存在变量中,无需编写任何进一步的代码来访问该项目。

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

for index in range(len(lst)):   # or xrange
    # you will have to write extra code to get the element
  1. 创建一个变量来保存索引(使用while

index = 0
while index < len(lst):
    # You will have to write extra code to get the element
    index += 1  # escape infinite recursion
  1. 总有另一种方式

如前所述,还有其他方法可以做到这一点,这里没有解释,它们甚至可能更适用于其他情况。 例如,将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. 分别使用indexvalue

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.您可以将index号更改为任何增量。

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 方法

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

# 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方法是最快的迭代方法。

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

您可以在字符串文字中使用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]

根据这个讨论: 对象的列表索引

循环计数器迭代

当前循环遍历索引的习惯用法使用了内置的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 – 循环计数器迭代

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

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

如果我要迭代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])

在您的问题中,您写道“我如何访问循环索引,在这种情况下从 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

如果列表中没有重复值:

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

此问题的最佳解决方案是使用enumerate内置函数。

enumerate返回一个tuple ,其中第一个值是索引,第二个值是该索引处的列表元素。

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)

你也可以试试这个:

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

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

您可以简单地使用诸如count之类的变量来计算列表中元素的数量:

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

除了上面所有的优秀答案之外,这里还有一个解决这个问题的方法,当使用 pandas 系列对象时。 在许多情况下,pandas 系列具有无法使用enumerate() function 访问的自定义/唯一索引(例如,唯一标识符字符串)。

 xs = pd.Series([8, 23, 45]) xs.index = ['G923002', 'G923004', 'G923005'] print(xs)

Output:

 # G923002 8 # G923004 23 # G923005 45 # dtype: int64

我们可以在下面看到enumerate()没有给我们想要的结果:

 for id, x in enumerate(xs): print("id #{} = {}".format(id, x))

Output:

 # id #0 = 8 # id #1 = 23 # id #2 = 45

我们可以使用.items()在 for 循环中访问 pandas 系列的索引:

 for id, x in xs.items(): print("id #{} = {}".format(id, x))

Output:

 # 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
    • 我们可以将元组作为变量访问,用逗号 ( , ) 分隔

谢谢。 让我在你的祈祷中。

您可以使用 enumerate 迭代列表并使用start=1因为它将默认为 0,这意味着它将从 0 开始计数。

下面是一个例子:

for index,val in enumerate(ints,start=1):
     print(f"item #{index} = {val}")

此外,使用f-strings是获取请求输出的一种快速方法,并且它更具可读性,因为您可以将 index 和 val 直接传递给 {}-placeholder。

输出:

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

使用 enumerate 遍历列表

ints = [8, 23, 45, 12, 78]
for idx,val in enumerate(ints):
    print('item #{} = {}'.format(idx+1, val))

输出:

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

可以通过以下代码实现:

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

将“计数器”变量设置为初始化程序的循环,该变量将作为参数,在格式化字符串时作为项目编号。

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

这很好地达到了目的:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM