为什么我们在这里使用Lambda作为函数参数?

时间:2018-04-29 18:45:41

标签: python python-3.x python-2.7 list

以下代码几乎没有问题来查找列表是否已排序:

为什么我们在这里使用lambda作为关键?是否总是意味着列表的关键字可以这样导出?

在枚举循环中,我们为什么要比较key(el) < key(lst[i])而不是key(el) <key(el-1)lst[i+1] <lst[i]

def is_sorted(lst, key=lambda x:x):
    for i, el in enumerate(lst[1:]):
        if key(el) < key(lst[i]): # i is the index of the previous element
            return False
    return True

hh=[1,2,3,4,6]
val = is_sorted(hh)
print(val)  

(注意:上面的代码取自this SO answer

4 个答案:

答案 0 :(得分:1)

enumerate同时产生索引和当前元素:

for i, el in enumerate(lst):
    print(i,el)

会打印:

0 1
1 2
2 3
3 4
4 6

通过将列表切换为一个(删除第一个元素),代码引入了索引和当前元素之间的转换,并且它允许仅通过索引访问一次(不被视为pythonic以在列表上使用索引时完全迭代它们

拉链(交错)列表和列表的切片版本仍然更好/ pythonic,并将比较传递给all,不涉及索引,更清晰的代码:

import itertools

def is_sorted(lst, key=lambda x:x):
    return all(key(current) < key(prev) for prev,current in zip(lst,itertools.islice(lst,1,None,None)))

切片由islice完成,不会生成额外的列表(否则它与lst[1:]相同)

键函数(此处:默认情况下为identity函数)是将值从值转换为可比较值的函数。对于整数,身份是可以的,除非我们想要反向比较,在这种情况下我们将通过lambda x:-x

答案 1 :(得分:1)

此代码扫描列表以查看它是否从低到高排序。第一个问题是决定什么&#34;低&#34;和&#34;高&#34;任意类型的意思。它很容易整数,但用户定义的类型呢?因此,作者允许您传递一个函数,该函数将类型转换为其比较以您希望的方式工作的类型。

例如,假设您要对元组进行排序,但根据您知道为整数的第3项,它将为key=lambda x: x[2]。但是作者提供了一个默认的key=lamba x:x,它只返回它为已经是自己的排序键的项提供的对象。

第二部分很简单。如果任何项目小于它之前的项目,那么我们找到一个不低到高的例子。它起作用的原因在于评论 - i是直接在el之前的元素的索引。我们知道这一点,因为我们列举了列表的第二个和后面的元素(enumerate(lst[1:])

答案 2 :(得分:0)

关键不在于lambda“派生”了列表的键。相反,它是一个允许您选择键的功能。也就是说,给定X类型的对象列表,您将使用什么属性来比较它们?默认值是标识函数 - 即使用每个元素的普通值。但你可以在这里选择任何东西。

你确实可以通过比较lst[i+1] < lst[i]来编写这个函数。但是,您无法通过比较key(el) < key(el-1)来编写它,因为el是元素本身的值,而不是索引。

答案 3 :(得分:0)

这是一个测试列表是否已排序的函数,作为内置sorted函数的示例。此函数采用关键字参数key,该参数用于列表中的每个元素以计算其比较值:

>>> sorted([(0,3),(1,2),(2,1),(3,0)])
[(0, 3), (1, 2), (2, 1), (3, 0)]
>>> sorted([(0,3),(1,2),(2,1),(3,0)],key=lambda x:x[1])
[(3, 0), (2, 1), (1, 2), (0, 3)]

您的函数中的key关键字是为了能够模仿sorted的行为:

>>> is_sorted([(0,3),(1,2),(2,1),(3,0)])
True
>>> is_sorted([(0,3),(1,2),(2,1),(3,0)],key=lambda x:x[1])
False

默认lambda就是模仿默认行为,其中没有任何更改。