2015-06-21 5 views
7

ho molto spesso scrivere codice come:funtori Trivial

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

dove vorrei scrivere:

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

utilizzando:

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

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

Ci sono functor-creatori come idx_f e attr_f in python, e sono più chiari se usati rispetto a lambda?

risposta

11

Il modulo operator ha operator.attrgetter() e operator.itemgetter() che fare proprio questo:

from operator import attrgetter, itemgetter 

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

Queste funzioni anche prendere più di un argomento, al punto che essi torneranno una tupla contenente il valore per ogni argomento:

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

La funzione attrgetter() accetta anche nomi tratteggiate, in cui si può raggiungere gli attributi di attributi:

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

grande! Ricordo di aver usato in questo modo, ma non sono riuscito a trovarli su Google. – Herbert