在阅读一些代码时,我遇到了以下我无法理解的片段。是否有人能够指导/提供提示/链接或下面第3行的基本解释
def do_store(*args, **kwargs):
try:
key = (args, tuple(sorted(kwargs.items(), key=lambda i:i[0])))
results = f._results
主要是,以下是做什么的?
key=lambda i:i[0]
答案 0 :(得分:12)
使用lambda
关键字,您可以创建“匿名函数”。它们没有(也不需要)名称,因为它们会立即(通常)分配给回调函数。
lambda i:i[0]
只是函数的主体
def f(i):
return i[0]
key
函数的sorted
参数必须是计算给定项目的排序键的函数。您还可以传递上面定义的函数(名称)f
,或者使用lambda
函数以获得更好的可读性。
正如tobias_k's回答中所述,在这段代码中,整个key
参数都是无用的。
答案 1 :(得分:9)
其他答案已经很好地解释了lambda
和sorted
key
参数的作用。简而言之:
key
用于为排序提供comparison key function,让我们称之为 f ,这样如果 f(x)< f(y),然后 x 将出现在排序列表中 y 之前。lambda
以快速而整洁的方式创建这样的函数,而不需要为那一种创建def
;你也可以使用任何其他功能(你自己的定义,内置等)。但是,要回答key=lambda i:i[0]
所做的问题,代码中的:什么都没有!
更确切地说,它告诉sorted
按要排序的元组中的元组的第一个元素进行排序,该元素由kwargs.items()
生成,即(key, value)
列表元组。但是,按第一个元素排序是元组的默认排序行为,只有当它们相等时,它才会按第二个元素排序,依此类推。但由于这些是字典的(keys, values)
,因此没有两个元组具有相同的第一个元素,因此使用此特定键函数与默认排序完全相同。
您也可以使用key = (args, tuple(sorted(kwargs.items())))
。
如果你问为什么它会这样做:这个函数似乎用于memoization,映射函数参数(存储在args
和kwargs
)先前计算的值。为此,必须将kwargs
字典转换为元组,因为字典不可清除,即它不能用作另一个字典的键。并且为了确保相同的字典总是产生相同的元组,必须对其进行排序,因为字典是无序的。
答案 2 :(得分:7)
三种等效的写法:
sorted(kwargs.items(), key=lambda i:i[0])
(这是你拥有的那个)
def first_item(aList): return aList[0]
sorted(kwargs.items(), key=first_item)
from operator import itemgetter
sorted(kwargs.items(), key=itemgetter(0))
在所有情况下,参数key
都会传递一个带有一个参数并返回该参数的第一个元素的函数。
lambda只是一种速记,可以避免给函数命名。赋予函数名称可以帮助人们阅读代码,尤其是在表达式更复杂的情况下。 itemgetter
函数具有轻微的速度优势,但不具备灵活性,只需返回一个或多个项目即可;如果您想进一步操纵这些项目(例如小写),您必须使用def
或lambda
。
答案 3 :(得分:4)
不提及第二个参数, key=lambda i:i[0]
,kwargs将按其全名排序。例如在通话中
do_store(abc=1, xyz=2, nji=3)
kwargs是一个词典{abc:1,xyz:2,nji:3}而sorted(kwargs.items())
将是[('abc', 1), ('nji', 3), ('xyz', 2)]
。默认密钥只是lambda i: i
(即对于kwargs中的每个元素,我们使用elemnt进行比较)。在你的例子中,我们将只使用item的第一个对象(即只有dict键,因为item是一对(key,value))
答案 4 :(得分:1)
Lambda允许您使用表达式创建简单的匿名函数。在这种情况下,匿名函数接受单个参数'i'并返回索引为零的'i'内的元素。
在这种情况下,目的是创建一个函数来选择'sorted()'函数使用的排序键。