2012-12-08 55 views
8

我有以下的解释:lambda函数

student_loan_portfolio = { 
    'loan1': {'rate': .078, 'balance': 1000, 'payment': 100, 'prepayment': 0}, 
    'loan2': {'rate': .0645, 'balance': 10, 'payment': 5, 'prepayment': 0}, 
    'loan3': {'rate': .0871, 'balance': 250, 'payment': 60, 'prepayment': 0}, 
    'loan4': {'rate': .0842, 'balance': 200, 'payment': 37, 'prepayment': 0}, 
    'loan5': {'rate': .054, 'balance': 409, 'payment': 49, 'prepayment': 0}, 
    'loan6': {'rate': .055, 'balance': 350, 'payment': 50, 'prepayment': 0} 
} 

我想通过含词典(与键loan1通过loan6)迭代中含有最高的字典中键的顺序'rate'值在其各自的嵌套字典中。也就是说,我想在loan3,loan4,loan1,loan2,loan6的顺序进行迭代,loan5

由于@Jame夏普要做到这一点,我知道最简单的方法是:

for k,v in sorted(student_loan_portfolio.items(), key=lambda (k,v): v['rate'], reverse=True): 

我我现在正在阅读关于lambda的内容,并且无法真正理解这个工作原理的方式和原因。 首先,v ['rate']我相信会返回这些字典键的值。但它似乎应该是某种语法错误。什么是v ['rate']引用以及语法背后的逻辑是什么?

在相关说明中,为什么我们必须将lambda函数的输入指定为元组?

以下情况如何不同?

#1 

>>>f = lambda x,y,z:x + y + z 
>>>f(1,2,3) 

#6 

>>>f = lambda (x,y,z): x + y + z 
>>>f(1,2,3) 

Traceback (most recent call last): 
    File "<pyshell#48>", line 1, in <module> 
    f(1,2,3) 
TypeError: <lambda>() takes exactly 1 argument (3 given) 

谢谢您的澄清。

+3

第二个预计3值的打包输入? 'f((1,2,3))' –

回答

5

student_loan_portfolio.items()上的items()方法返回键/值元组列表。所以它返回类似[ ('loan1', dictOfLoan1), ('loan2', dictOfLoan2), ...]。 lambda接受该元组作为参数,并从值字典中读取“rate”项(即,它读取dictOfLoan1['rate'],dictOfLoan2['rate']等)。

你可以通过使用,而不是你有lambda,lambda item: item[1]['rate']达到相同的效果。 item是一个元组(key, value),所以item[1]是值。

你的两个lambda例子的区别在于第一个接受三个参数,而第二个接受三个元组的元组。定义一个接受元组作为参数但将其内容解压缩到单独局部变量的函数的能力是Python 3的一个怪癖(参见PEP 3113)。

+0

好的,谢谢@BrenBarn。我做了一些更多的实验,所以v ['rate']的原因不是语法错误,因为v是一个字典,对吧? – cdelsola

+0

@ user1816858:是的,基本上。你有一本字典,其值也是字典。 (如果它不是字典,它仍然不是*语法*错误,但如果它不支持使用'[]'的项目访问,则会出现错误。) – BrenBarn

8

lambda (k,v): v['rate']是一个函数,它接受单个参数(2元组),并返回元组中第二个条目的'rate'键。它相当于lambda t: t[1]['rate']

lambda x,y,z:x + y + z是一个函数,它取3个值并返回它们的总和。

lambda (x,y,z): x + y + z是一个函数,它接受1个值(一个3元组),并返回其元素的总和。