Trivial functors

199 views Asked by At

I very often write code like:

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

where I would like to write:

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

using:

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

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

Are there functor-creators like idx_f and attr_f in python, and are they of clearer when used than lambda's?

1

There are 1 answers

1
Martijn Pieters On BEST ANSWER

The operator module has operator.attrgetter() and operator.itemgetter() that do just that:

from operator import attrgetter, itemgetter

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

These functions also take more than one argument, at which point they'll return a tuple containing the value for each argument:

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

The attrgetter() function also accepts dotted names, where you can reach attributes of attributes:

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