【问题标题】:Working of Enumerate in PythonPython中枚举的工作
【发布时间】:2016-02-12 17:48:20
【问题描述】:

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

例如: 我有两个 Lists 值 L1 = [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] 在上述逻辑中的工作原理。提前致谢。非常感谢您的帮助。

【问题讨论】:

标签: python list enumerate


【解决方案1】:

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

L1 = [9, 12, 9, 6]

变成

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

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

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

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

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

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

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

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

【讨论】:

  • 感谢您的解释,我不明白operator.itemgetter(1) 是如何工作的,括号中应该给出什么值,在这种情况下 1 是怎么回事?
【解决方案2】:

enumerate() 只是为输入迭代中的每个项目生成原始值加上索引的元组,顺序为(index, item)。见What does enumerate mean?

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

您可以轻松地使用它来查看max() 总是从列表中返回一个原始值,但在使用key 函数时会改变返回的值。您可以使用任何函数,包括使用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) 创建一个始终选择 second 元素的对象(Python 从 0 开始计数),operator.itemgetter(2) 将在您每次调用它时返回第三个元素:

>>> 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,你会得到最大的“元组”;元组通过包含的第一个不同的元素进行比较。所以(1, 2) 大于(1, 0) 因为第二个元素2 大于0。但是(2, 1) 比(1, 1) 大,因为第一个元素不同,2 更大。由于enumerate() 添加了递增的索引(从0 开始),这意味着没有key 的max() 将始终选择last 元素:

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

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

请注意,在这里使用enumerate() 是多余的。您可以只使用zip() function 来配对L1 和L2:

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

zip() 将L1 和L2 的元素配对,生成带有(9, 2)、(12, 3) 等的元组。max() 从该序列中挑选最大的元组,首先查看第一个元素(取自L1)。

【讨论】:

  • 太棒了,谢谢。我也会研究好的zip。感谢您的详细解释。
【解决方案3】:

来自帮助:

关于内置模块内置函数 max 的帮助:

最大(...) 最大值(可迭代,* [,默认=obj,键=函数])-> 值 max(arg1, arg2, *args, *[, key=func]) -> 值

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.

还有

关于模块操作符中的类 itemgetter 的帮助:

类 itemgetter(builtins.object) | itemgetter(item, ...) --> itemgetter 对象 | |返回一个可调用的对象,该对象获取 从其操作数中给定项目。 |在 f = itemgetter(2) 之后,调用 f(r) 返回 r[2]。 |在 g = itemgetter(2, 5, 3) 之后,调用 g(r) 返回 (r[2], r[5], r[3])

所以,itemgetter 就像它的名字所说的那样:它从 列表的元素。 在这种情况下,第二个元素(索引为 1 的元素)。 这就是你要做的:

你在 enumerate 生成的输出上调用 max:

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

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

key=operator.itemgetter(1)),

即列表中每个元素的第二个值。然后 max 返回 它找到的元素,其形式为 (index, value)。

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 我试图用上面的例子来解释枚举和键操作符
    猜你喜欢
    • 2015-08-08
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 2022-01-06
    • 1970-01-01
    • 2018-12-09
    相关资源
    最近更新 更多