2010-01-16 5 views
2

Je cherche des conseils pour faire ce qui suit d'une manière plus pythonique.Façon pythonique de trier la liste des objets par une valeur dict (par clé) contenue dans l'objet

Tenir compte:

class MyObj(object): 
    def __init__(self): 
     self.dict_properties = {} 

Supposons que j'ai une liste qui contient plusieurs instances MyObj:

mylist = [<__main__.MyObj object at 0x1005e3b90, ...] 

Maintenant, je veux trier mylist en fonction de la valeur d'une certaine clé dans dict_properties en MyObj.

Qu'est-ce que le travail est:

mylist.sort(lambda x,y: cmp(x.dict_properties['mykey'], 
          y.dict_properties['mykey'])) 

mais à peine sent pythonique.

Y a-t-il un meilleur moyen (en utilisant peut-être operator.attrgetter)?

+0

Les étiquettes ne reflètent pas le niveau de la personne qui demande. Personne ne prétend que vous êtes un débutant Christophe, mais chaque jour il y aurait au moins quelques questions à poser ** exactement la même chose que vous **, et comme la réponse est facile à trouver dans les docs, Par conséquent, une question doit être taguée [débutant]. Veuillez arrêter de supprimer cette balise. Merci. – SilentGhost

+0

si vous doutez de ma réclamation sur la fréquence ou les doublons s'il vous plaît examiner: http://stackoverflow.com/questions/tagged/python+sorting – SilentGhost

+0

J'ai une opinion différente sur la nécessité d'un tag «débutant» sur cette question: contrairement à la plupart D'autres questions de ce type, j'ai fourni un moyen de travailler pour ce faire et ensuite spécifiquement demandé des alternatives/d'autres façons de le faire d'une manière plus «pythonique». Semble la réponse était évidente (une seule approche dans les réponses) même si je ne me suis pas immédiatement rendu compte que c'était supposé être le plus propre =. Mais je vais juste laisser la balise alors, puisque je ne suis pas intéressé par une guerre (supplémentaire) de rollback/editing. – ChristopheD

Répondre

9
mylist.sort(key=lambda x: x.dict_properties['mykey']) 

est beaucoup plus simple et rapide. Vous pouvez atteindre operator et essayer de composer un attrgetter et un itemgetter, mais un simple lambda (ou def) semble le plus simple ici.

+0

Merci beaucoup. Semble que c'est en effet une manière très propre de fournir cette fonctionnalité ;-) – ChristopheD

+0

Seul point négatif serait que cela ne fonctionnerait pas en dessous de python 2.4, n'est-ce pas? (bien que je doute qu'il y ait encore beaucoup d'installations python en dessous de cette version). – ChristopheD

+1

@ChristopheD, oui, 'key =' a été introduit en 2.4 (dont la version finale était un peu plus de 5 ans). Toute personne qui a besoin de supporter des versions de 6 ans ou plus devrait sans doute s'attendre à mentionner explicitement ce fait, j'imagine ;-). –

3

Je venais de faire:

mylist.sort(key=lambda o: o.dict_properties["kykey"])

Vous pouvez également overide cmp sur la classe.

+0

Merci beaucoup. J'ai considéré le remplacement de cmp sur la classe mais cela impliquerait de perdre une partie de la dynamique de choisir 'mykey' de manière variable (à moins que je me trompe) – ChristopheD

1

Si la vitesse est un problème, utilisez décorer tri-undecorate:

mylist_decorated = [(elem.dict_properties['mykey'], elem) for elem in mylist] 
    mylist_decorated.sort() 
    mylist = [elem[1] for elem in mylist_decorated] # or zip(*mylist_decorated)[1] :) 
  • cette façon sort() peut se propager ses ailes.
+1

C'est à peu près ce que le paramètre clé de la méthode de tri fait pour vous. Si vous utilisez Python <2.4 alors ce serait un moyen sensé de le faire, sinon vous faites juste du travail pour vous-même. –

+0

Ici vous m'avez eu! Merci pour le tuyau. –

Questions connexes