Python 中枚举的工作

Working of Enumerate in Python

我是 Python 的新手,我目前正在解决问题以提高我的编码技能。我遇到了一个问题,我在 List 中找到最大值,它在另一个 List 中的对应值具有相同的 index 个最大值。

例如: 我有两个 ListsL1 = [9, 12, 9 ,6]L2 = [2, 3, 4, 5] 我必须在 List L1 中找到最大值,最大值的索引应该在 List L2 中找到它的对应值。

Max value in List L1 - 12
Index of the max value - 1
print L2[1] -> 3

所以为了实现上面的逻辑,我重新找了一个方法,得到了。但我无法理解逻辑是如何工作的。

import operator   
index, value = max(enumerate(l1), key=operator.itemgetter(1))
print value, 
print l2[index]

输出:12 3

为了理解上面的函数是如何工作的,我试着分别打印每个部分,但仍然无法理解逻辑是如何工作的。

print l1 - [9, 12, 9 , 6]
print l2 - [2, 3, 4, 5]
print list(enumerate(l1)) - [<0, 9>, <1, 12>, <2, 9>, <3, 6>]
print list(enumerate(l2)) - [<0, 2>, <1, 3>, <2, 4>, <3, 5>]
print max(enumerate(l1)) - <3, 6>
print max(enumerate(l2)) - <3, 5>

请帮助我理解 enumerate 函数和 key=operator.itemgetter(1))[0] 在上述逻辑中是如何工作的。提前致谢。非常感谢您的帮助。

enumerate() 简单地为输入可迭代中的每个项目生成具有原始值和索引的元组,顺序为 (index, item)。参见 What does enumerate mean?

max() 给定一个键,从序列中选出最大值。默认键是使用值本身,但是对于 operator.itemgetter(1),您告诉 max() 只注意每个输入项的第二个值。

您可以很容易地使用它来查看 max() 总是 return 列表中的原始值,但在使用 [=20] 时会改变 returned 的值=] 功能。您可以使用任何函数,包括使用 lambda:

创建的函数
>>> L1 = [9, 12, 9, 6]
>>> max(L1)  # straight up, biggest value in the list
12
>>> max(L1, key=lambda v: len(str(v)))  # value with the most digits, 12 has two digits
12
>>> max(L1, key=lambda v: abs(v - 10))  # value furthest from 10; 6 is the furthest
6

当您用至少一个参数调用 operator.itemgetter() 时,它会生成一个对象,当用序列调用时,它将使用参数作为该序列的索引。 operator.itemgetter(1) 创建一个始终选择 第二个 元素的对象(Python 从 0 开始计数),operator.itemgetter(2) 会 return 每次调用第三个元素:

>>> from operator import itemgetter
>>> ig2 = itemgetter(2)
>>> ig2
operator.itemgetter(2)
>>> ig2(L1)  # the 3rd element in L1 is 9
9

鉴于 enumerate() 将原始值放在它生成的每个元组的第二个位置,max() 根据原始输入列表中的值从元组序列中选择最大值。但是,它会保持 enumerate() 生成的元组完好无损。

如果你省略了 key,你会得到最大的 'tuple';元组由包含的第一个不同元素进行比较。所以 (1, 2) 大于 (1, 0) 因为第二个元素 2 大于 0。但是 (2, 1)(1, 1) 大,因为第一个元素不同并且 2 是更大的一个。由于 enumerate() 添加递增索引(从 0 开始),这意味着没有 keymax() 将始终选择 last 元素:

>>> max(enumerate(l1))  # last element is (3, 6)
(3, 6)

选择该元素是因为 3 是最高索引。

请注意,这里使用 enumerate() 有点矫枉过正。您可以只使用 zip() function 来配对 L1L2

l1max, corresponding_l2 = max(zip(L1, L2))

zip()L1L2 的元素配对,生成具有 (9, 2)(12, 3) 等的元组。max() 选择该序列中最大的元组,首先查看第一个元素(取自 L1)。

@Dev: Enumerate 函数只是打印列表,它的索引值和键是你想对数据结构进行操作的东西,请看下面的代码

index, value = min(enumerate(l1), key=operator.itemgetter(1))
print value
6
print index
3
index, value = max(enumerate(l1), key=operator.itemgetter(1))
print index
1
print value
12
sorted(enumerate(l1), key=operator.itemgetter(1))
[(3, 6), (0, 9), (2, 9), (1, 12)]
sorted(enumerate(l1), key=operator.itemgetter(0))
[(0, 9), (1, 12), (2, 9), (3, 6)]

enumerate 创建一个生成器函数,可以有效地将值列表转换为元组列表。

L1 = [9, 12, 9, 6]

变成

[(0, 9), (1, 12), (2, 9), (3, 6)]

max 函数查找该列表中的最大值。如果没有向 max 提供其他参数,它会将 tuples 相互比较,并且此项将是最大值 - (3, 6)。但这不是我们想要的。我们不希望它在比较中使用 enumerate 数字。

max 接受一个 key 参数,它应该是一个接受一个参数的函数,这将是列表中的值,并且 return 应该是一个值用于对列表进行排序并选择最大值。在这种情况下,我们希望根据每个元组中的第二个数字对列表进行排序(即 (3, 6) 中的 6)。

operator.itemgetter 是一个函数,return 是一个函数,它将 return 它所调用的事物的索引项。例如:

L1 = [3, 4, 6, 2]
f = operator.itemgetter(0)
f(L1)
# 3

f = operator.itemgetter(2)
f(L1)
# 6

在这种情况下,它使用 operator.itemgetter(1),它将 return (3, 6)

中的 6

所以我们从max(enumerate(l1), key=operator.itemgetter(1))得到的结果是一个tuple,其中最大值的索引和L1中的最大值。

来自帮助:

Help on built-in function max in module builtins:

max(...) max(iterable, *[, default=obj, key=func]) -> value max(arg1, arg2, *args, *[, key=func]) -> value

With a single iterable argument, return its biggest item. The
default keyword-only argument specifies an object to return if
the provided iterable is empty.
With two or more arguments, return the largest argument.

还有

Help on class itemgetter in module operator:

class itemgetter(builtins.object) | itemgetter(item, ...) --> itemgetter object | | Return a callable object that fetches the given item(s) from its operand. | After f = itemgetter(2), the call f(r) returns r[2]. | After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])

因此,itemgetter 的功能如其名:它从 列表的元素。 在这种情况下,第二个元素(索引为 1 的元素)。 这就是你要做的:

您对 enumerate 生成的输出调用 max:

[<0, 9>, <1, 12>, <2, 9>, <3, 6>]

并告诉它根据以下定义的键确定最大值:

key=operator.itemgetter(1)),

即列表中每个元素的第二个值。然后最大值 returns 它找到的元素,形式为 (index, value).