2012-12-08 21 views
8

Mam następujący słownik:funkcja lambda w sortowych słowniku listowego

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} 
} 

Chciałbym iterację zawierającego słowniku (z kluczami loan1 przez loan6) w celu klucza zawierającego słownik z najwyższą Wartość "rate" w odpowiednim zagnieżdżonym słowniku. Oznacza to, że chciałbym iteracyjne w kolejności loan3, loan4, loan1, loan2, loan6, loan5

Dzięki @Jame Sharpa najprostszym sposobem na to, że wiem, że zrobić to:

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

I teraz czytam o lambdzie i nie mogę dokładnie zrozumieć, jak i dlaczego to działa. Po pierwsze, v ['rate'] Wierzę, że zwraca wartość tych kluczy słownika. Ale wydaje się, że powinien to być jakiś błąd składniowy. czym jest odniesienie v ['rate'] i jaka jest logika stojąca za składnią?

W powiązanej uwadze, dlaczego, musimy określić dane wejściowe do funkcji lambda jako krotki?

A jakie są następujące przypadki?

#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) 

Dziękuję za wyjaśnienia.

+3

Druga oczekuje spakowanego wejścia z 3 wartościami? 'f ((1,2,3))' –

Odpowiedz

5

Metoda items() na student_loan_portfolio.items() zwraca listę krotek kluczy/wartości. Zwraca więc coś w rodzaju [ ('loan1', dictOfLoan1), ('loan2', dictOfLoan2), ...]. Wartość lambda akceptuje tę krotkę jako argument i odczytuje element "rate" z wartości dict (tj. Odczytuje dictOfLoan1['rate'], dictOfLoan2['rate'] itp.).

Można osiągnąć ten sam efekt, używając zamiast, zamiast lambda, lambda item: item[1]['rate']. item jest krotką (key, value), więc item[1] jest wartością.

Różnica między Twoimi dwoma przykładami lambda polega na tym, że pierwszy akceptuje trzy argumenty, a drugi przyjmuje pojedynczy argument, który jest krotką trzyelementową. Zdolność do zdefiniowania funkcji, która akceptuje krotki jako argumenty, ale rozpakowuje ich zawartość do oddzielnych zmiennych lokalnych, była dziwactwem Pythona, który został usunięty w Pythonie 3 (patrz PEP 3113).

+0

OK dzięki @BrenBarn. Zrobiłem trochę więcej eksperymentów, więc powodem v ["rate"] nie jest błąd składniowy, ponieważ v jest słownikiem, prawda? – cdelsola

+0

@ user1816858: Tak, w zasadzie. Masz słownik, którego wartościami są również słowniki. (Jeśli nie był to słownik, to nadal nie byłby to błąd * składni *, ale pojawiłby się błąd, gdyby nie obsługiwał dostępu do elementu za pomocą '[]'.) – BrenBarn

8

lambda (k,v): v['rate'] to funkcja, która pobiera pojedynczy argument (2-krotna) i zwraca klucz 'rate' drugiego wpisu w krotce. Jest to odpowiednik funkcji lambda t: t[1]['rate'] . Jest to funkcja, która pobiera 3 wartości i zwraca ich sumę.

lambda (x,y,z): x + y + z to funkcja, która przyjmuje 1 wartość (3-tkę) i zwraca sumę jej elementów.