2015-06-21 21 views
7

ja bardzo często pisania kodu, takich jak:Banalne funktory

sorted(some_dict.items(), key=lambda x: x[1]) 
sorted(list_of_dicts, key=lambda x: x['age']) 
map(lambda x: x.name, rows) 

gdzie chciałbym napisać:

sorted(some_dict.items(), key=idx_f(1)) 
sorted(list_of_dicts, key=idx_f('name')) 
map(attr_f('name'), rows) 

używając:

def attr_f(field): 
    return lambda x: getattr(x, field) 

def idx_f(field): 
    return lambda x: x[field] 

Czy funktor-twórcy jak idx_f i attr_f w python, i czy są one bardziej przejrzyste, gdy są używane niż lambda?

Odpowiedz

11

Moduł operator ma operator.attrgetter() i operator.itemgetter() że nie tylko to:

from operator import attrgetter, itemgetter 

sorted(some_dict.items(), key=itemgetter(1)) 
sorted(list_of_dicts, key=itemgetter('name')) 
map(attrgetter('name'), rows) 

Funkcje te biorą również więcej niż jeden argument, w którym momencie oni powrotu krotki zawierającej wartość dla każdego argumentu:

# sorting on value first, then on key 
sorted(some_dict.items(), key=itemgetter(1, 0)) 

# sort dictionaries by last name, then first name 
sorted(list_of_dicts, key=itemgetter('last_name', 'first_name')) 

funkcja attrgetter() akceptuje również przerywane nazwy, gdzie może osiągnąć atrybuty atrybutów:

# extract contact names 
map(attrgetter('contact.name'), companies) 
+0

świetnie! Pamiętam, że korzystałem z nich w ten sposób, ale nie mogłem ich znaleźć w Google. – Herbert