python: combine sort-key-functions itemgetter and str.lower

function, key, python, sorting

Solution

In the general case, you'll want to write your key-extraction function for sorting purposes; only in special (though important) cases it happens that you can just reuse an existing callable to extract the keys for you, or just conjoin a couple of existing ones (in a "quick and dirty" way using `lambda`, since there's no built-in way to do function composition).

If you often need to perform these two kinds of operations for key extraction (get an item and call a method on that item), I suggest:

def combiner(itemkey, methodname, *a, **k):
  def keyextractor(container):
    item = container[itemkey]
    method = getattr(item, methodname)
    return method(*a, **k)
  return keyextractor

so `listofdicts.sort(key=combiner('name', 'lower'))` will work in your case.

Note that while excessive generalization has costs, tasteful and moderate generalization (leaving the item key, method name, and method arguments if any, as runtime-determined, in this case) generally has benefits -- one general function, not more complex than a dozen specific and specialized ones (with the extractor, method to call, or both, hardwired in their code), will be easier to maintain (and, of course, much easier to reuse!-).

Problem

I want to sort a list of dictionaries by dictionary key, where I don't want to distinguish between upper and lower case characters. ``` dict1 = {'name':'peter','phone':'12355'} dict2 = {'name':'Paul','phone':'545435'} dict3 = {'name':'klaus','phone':'55345'} dict4 = {'name':'Krishna','phone':'12345'} dict5 = {'name':'Ali','phone':'53453'} dict6 = {'name':'Hans','phone':'765756'} list_of_dicts = [dict1,dict2,dict3,dict4,dict5,dict6] key_field = 'name' list_of_dicts.sort(key=itemgetter(key_field)) # how to combine key=itemgetter(key_field) and key=str.lower? for list_field in list_of_dicts: print list_field[key_field] ``` should provide ``` Ali, Hans, klaus, Krishna, Paul, peter ``` and not ``` klaus, peter, Ali, Hans, Krishna, Paul ```

Original source