【问题标题】:Why did we use Lambda as function argument here?为什么我们在这里使用 Lambda 作为函数参数?
【发布时间】:2018-04-29 18:45:41
【问题描述】:

关于以下代码的几个问题,用于查找列表是否已排序:

为什么我们在这里使用 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

【问题讨论】:

  • 我不明白你的第三个问题。将 key(el) 与自身进行比较有什么意义?
  • @DanielRoseman - 编辑了一些被截断的文本。
  • 那是因为列表切片使索引移位。如果你问我,这是一种笨拙的做法。
  • @ekhumoro - 我正在寻找解决方案,这是一些教程给我的解决方案。我正在寻找更符合逻辑的东西来记住。
  • 所以你有一个问题,而不是告诉我们你找到的解决方案..这听起来像xy-problem - 你想解决什么问题?

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


【解决方案1】:

此代码扫描列表以查看它是否从低到高排序。第一个问题是确定任意类型的“低”和“高”意味着什么。整数很容易,但是用户定义的类型呢?因此,作者允许您传入一个函数,该函数将类型转换为按您希望的方式进行比较的某种东西。

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

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

【讨论】:

    【解决方案2】:

    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:]一样)

    关键函数(这里:默认情况下的标识函数)是将值转换为可比较值的函数。对于整数,恒等式是可以的,除非我们想反向比较,在这种情况下我们会通过lambda x:-x

    【讨论】:

    • 这些事情都是真的,但似乎没有回答任何 OP 的问题。
    【解决方案3】:

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

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

    【讨论】:

    • 感谢 lst[i+1]
    【解决方案4】:

    这是一个测试列表是否已排序的函数,例如内置 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 只是用来模仿默认行为,没有任何改变。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-18
      • 2016-05-04
      相关资源
      最近更新 更多