9
votes

Python: Combinez les fonctions de tri-clés de tri.

Je veux trier une liste de dictionnaires par la touche Dictionnaire, où je ne veux pas distinguer entre les majuscules et les minuscules.

klaus, peter, Ali, Hans, Krishna, Paul


0 commentaires

7 Réponses :


2
votes
def lower_getter(field):
    def _getter(obj):
        return obj[field].lower()
    return _getter

list_of_dicts.sort(key=lower_getter(key_field))

1 commentaires

Et en plus, cela fonctionnera automatiquement avec des cordes BYTTRESS et UNICODE.



15
votes

Que diriez-vous:

list_of_dicts.sort(key=lambda a: a['name'].lower())


0 commentaires

12
votes

Dans le cas général, vous voudrez écrire votre fonction d'extraction de clé à des fins de tri; Seulement dans des cas spéciaux (bien que importants), il arrive que vous puissiez simplement réutiliser une appelable existante pour extraire les clés pour vous, ou simplement conjointer un couple de personnes existantes (dans une "voie rapide et sale" en utilisant lambda , comme il n'y a pas de manière intégrée à faire la composition de fonction).

Si vous avez souvent besoin d'exécuter ces deux types d'opérations pour une extraction clé (obtenez un élément et appelez une méthode sur cet article), je suggère: xxx

donc listOfdics.sort (clé = combineur ("nom", "inférieur")) fonctionnera dans votre cas.

Notez que, tandis que la généralisation excessive comporte des coûts, une généralisation de bon goût et modéré (laissant la clé d'élément, le nom de la méthode et les arguments de la méthode, le cas échéant, comme étant déterminé par l'exécution, dans ce cas) ont généralement des avantages - une fonction générale, pas plus complexe que Une douzaine de celles spécifiques et spécialisées (avec l'extracteur, la méthode à appeler, ou les deux, câblées dans leur code), seront plus faciles à maintenir (et, bien sûr, beaucoup plus faciles à réutiliser! -).


0 commentaires

4
votes

Vous devriez probablement aller avec une Lambda pour des raisons de lisibilité. Mais comme une étude intéressante dans des fonctions d'ordre supérieur, voici la version étendue de Q-Combinator à Python (également appelé Combinateur d'oiseaux Queer). Cela vous permet de créer une nouvelle fonction en composant deux fonctions xxx

si vous inversez les définitions de la fonction interne et externe dans la fonction compose , vous obtenez le plus traditionnel b -Commerciateur (Bluebird). J'aime plus la combinaison Q-Combinator en raison de la similitude avec des tuyaux Unix.


0 commentaires

4
votes

Cette solution utilisera votre système locale système et, en bonus, il triera également d'autres caractères en fonction des paramètres régionaux actuels (mettra "¼" après "u" dans une locale allemande, etc.).

from locale import setlocale, strxfrm, LC_ALL
import operator

# call setlocale to init current locale
setlocale(LC_ALL, "")

def locale_keyfunc(keyfunc):  
  def locale_wrapper(obj):
    return strxfrm(keyfunc(obj))
  return locale_wrapper

list_of_dicts.sort(key=locale_keyfunc(operator.itemgetter("name")))


2 commentaires

Ceci est une bonne suggestion, changez simplement KeyFunc sur: def KeyFuncunc (DIC): retour Strxfrm (DIC ["Nom"])


Francesco: Il utilise maintenant un style d'usine plus personnalisable (bien qu'il puisse être spécialisé pour être plus rapide, cela compte rarement).



4
votes

Personnellement, je souhaite qu'il y ait deux fonctions dans la bibliothèque standard Python (probablement dans Functools):

lower = method_caller('lower')
get_name = itemgetter('name')
lowered_name = compose(lower, get_name)

list_of_dicts.sort(key=lowered_name)


0 commentaires

5
votes
from functools import partial

def nested_funcs(*funcs):
    return partial(reduce, lambda arg, func: func(arg), funcs)


sorted(list_of_dicts, key=nested_funcs(itemgetter('name'), str.strip, str.lower))

0 commentaires