Tu fais une copie complète de la liste avant de lui appliquer la méthode sort()
. En effet, cette méthode étant destructive (car in-place), c’est utile si tu veux la ré-utiliser la liste originale ailleurs.
Mais il y a plus simple encore. Python fournit une fonction sorted
qui te renvoie une nouvelle liste triée plutôt que de trier la liste originale sur place :
>>> l
[{'n': 'dupont', 'p': 'stephane', 's': 2500}, {'n': 'dubois', 'p': 'nicolas', 's': 7000}, {'n': 'ducon', 'p': 'phillipe', 's': 1250}, {'n': 'ducon', 'p': 'alice', 's': 4530}, {'n': 'dupont', 'p': 'jackie', 's': 2200}, {'n': 'lapin', 'p': 'jeannot'}, {'n': 'dubois', 'p': 'fanny', 's': 5000}, {'n': 'dupont', 'p': 'steven', 's': 1670}, {'n': 'durant', 'p': 'fabienne', 's': 550}, {'n': 'durant', 'p': 'eric', 's': 1300}]
>>> sorted(l, key=lambda d: d.get('s', 0))
[{'n': 'lapin', 'p': 'jeannot'}, {'n': 'durant', 'p': 'fabienne', 's': 550}, {'n': 'ducon', 'p': 'phillipe', 's': 1250}, {'n': 'durant', 'p': 'eric', 's': 1300}, {'n': 'dupont', 'p': 'steven', 's': 1670}, {'n': 'dupont', 'p': 'jackie', 's': 2200}, {'n': 'dupont', 'p': 'stephane', 's': 2500}, {'n': 'ducon', 'p': 'alice', 's': 4530}, {'n': 'dubois', 'p': 'fanny', 's': 5000}, {'n': 'dubois', 'p': 'nicolas', 's': 7000}]
>>> l
[{'n': 'dupont', 'p': 'stephane', 's': 2500}, {'n': 'dubois', 'p': 'nicolas', 's': 7000}, {'n': 'ducon', 'p': 'phillipe', 's': 1250}, {'n': 'ducon', 'p': 'alice', 's': 4530}, {'n': 'dupont', 'p': 'jackie', 's': 2200}, {'n': 'lapin', 'p': 'jeannot'}, {'n': 'dubois', 'p': 'fanny', 's': 5000}, {'n': 'dupont', 'p': 'steven', 's': 1670}, {'n': 'durant', 'p': 'fabienne', 's': 550}, {'n': 'durant', 'p': 'eric', 's': 1300}]
Par ailleurs, j’ai utilisé d.get('s', 0)
plutôt que d['s'] if 's' in d else 0
. Là encore, Python te fournit déjà de quoi récupérer une valeur par défaut en cas de clef non existante.
Dès lors que tu as un liste triée, tu peux récupérer le premier élément ([0]
) pour connaître le nom de famille qui gagne le moins, et le dernier élément ([-1]
) pour la famille qui gagne le plus.
Par contre, si tu ne veux pas compter les individu n’ayant pas d’attribut salaire s
, il faut les enlever avant de trier :
>>> liste_triée = sorted((p for p in l if 's' in p), key=lambda d: d['s'])
>>> liste_triée
[{'n': 'durant', 'p': 'fabienne', 's': 550}, {'n': 'ducon', 'p': 'phillipe', 's': 1250}, {'n': 'durant', 'p': 'eric', 's': 1300}, {'n': 'dupont', 'p': 'steven', 's': 1670}, {'n': 'dupont', 'p': 'jackie', 's': 2200}, {'n': 'dupont', 'p': 'stephane', 's': 2500}, {'n': 'ducon', 'p': 'alice', 's': 4530}, {'n': 'dubois', 'p': 'fanny', 's': 5000}, {'n': 'dubois', 'p': 'nicolas', 's': 7000}]
>>> liste_triée[0]['n']
'durant'
>>> liste_triée[-1]['n']
'dubois'
Ici, on peut noter l’utilisation de (p for p in l if 's' in p)
pour enlever tous les éléments qui n’ont pas d’attribut s
. Cela nous permet donc de ne pas prendre en compte ces éléments-là.
Si tu ne comprends pas la syntaxe, je t’encourage vivement à te renseigner dessus car elle est très courante en Python. Voici un document qui pourrait t’éclairer : Listes et générateurs en intension.