Dans l'exemple suivant, je voudrais trier les animaux par ordre alphabétique de leur catégorie, qui est stocké dans un dictionnaire d'ordre.

category = [{'uid': 0, 'name': 'mammals'},
            {'uid': 1, 'name': 'birds'},
            {'uid': 2, 'name': 'fish'},
            {'uid': 3, 'name': 'reptiles'},
            {'uid': 4, 'name': 'invertebrates'},
            {'uid': 5, 'name': 'amphibians'}]

animals = [{'name': 'horse', 'category': 0},
           {'name': 'whale', 'category': 2},
           {'name': 'mollusk', 'category': 4},
           {'name': 'tuna ', 'category': 2},
           {'name': 'worms', 'category': 4},
           {'name': 'frog', 'category': 5},
           {'name': 'dog', 'category': 0},
           {'name': 'salamander', 'category': 5},
           {'name': 'horse', 'category': 0},
           {'name': 'octopus', 'category': 4},
           {'name': 'alligator', 'category': 3},
           {'name': 'monkey', 'category': 0},
           {'name': 'kangaroos', 'category': 0},
           {'name': 'salmon', 'category': 2}]

sorted_animals = sorted(animals, key=lambda k: (k['category'])

Comment pourrais-je y parvenir? Merci.

0
Munshine 15 mars 2019 à 18:16

2 réponses

Meilleure réponse

Vous triez maintenant sur l'id de catégorie. Tout ce que vous devez faire est de mapper cet identifiant à une recherche pour un nom category donné.

Créez d'abord un dictionnaire pour les catégories afin de pouvoir directement mapper l'ID numérique au nom associé de la liste category, puis utilisez ce mappage lors du tri:

catuid_to_name = {c['uid']: c['name'] for c in category}

sorted_animals = sorted(animals, key=lambda k: catuid_to_name[k['category']])

Démo:

>>> from pprint import pprint
>>> category = [{'uid': 0, 'name': 'mammals'},
...             {'uid': 1, 'name': 'birds'},
...             {'uid': 2, 'name': 'fish'},
...             {'uid': 3, 'name': 'reptiles'},
...             {'uid': 4, 'name': 'invertebrates'},
...             {'uid': 5, 'name': 'amphibians'}]
>>> animals = [{'name': 'horse', 'category': 0},
...            {'name': 'whale', 'category': 2},
...            {'name': 'mollusk', 'category': 4},
...            {'name': 'tuna ', 'category': 2},
...            {'name': 'worms', 'category': 4},
...            {'name': 'frog', 'category': 5},
...            {'name': 'dog', 'category': 0},
...            {'name': 'salamander', 'category': 5},
...            {'name': 'horse', 'category': 0},
...            {'name': 'octopus', 'category': 4},
...            {'name': 'alligator', 'category': 3},
...            {'name': 'monkey', 'category': 0},
...            {'name': 'kangaroos', 'category': 0},
...            {'name': 'salmon', 'category': 2}]
>>> catuid_to_name = {c['uid']: c['name'] for c in category}
>>> pprint(catuid_to_name)
{0: 'mammals',
 1: 'birds',
 2: 'fish',
 3: 'reptiles',
 4: 'invertebrates',
 5: 'amphibians'}
>>> sorted_animals = sorted(animals, key=lambda k: catuid_to_name[k['category']])
>>> pprint(sorted_animals)
[{'category': 5, 'name': 'frog'},
 {'category': 5, 'name': 'salamander'},
 {'category': 2, 'name': 'whale'},
 {'category': 2, 'name': 'tuna '},
 {'category': 2, 'name': 'salmon'},
 {'category': 4, 'name': 'mollusk'},
 {'category': 4, 'name': 'worms'},
 {'category': 4, 'name': 'octopus'},
 {'category': 0, 'name': 'horse'},
 {'category': 0, 'name': 'dog'},
 {'category': 0, 'name': 'horse'},
 {'category': 0, 'name': 'monkey'},
 {'category': 0, 'name': 'kangaroos'},
 {'category': 3, 'name': 'alligator'}]

Notez que dans chaque catégorie , les dictionnaires ont été laissés dans l'ordre d'entrée relatif. Vous pouvez renvoyer un tuple de valeurs à partir de la clé de tri pour appliquer davantage un ordre de tri dans chaque catégorie, par exemple:

sorted_animals = sorted(
    animals,
    key=lambda k: (catuid_to_name[k['category']], k['name'])
)

Trierait par nom d'animal dans chaque catégorie, produisant:

>>> pprint(sorted(animals, key=lambda k: (catuid_to_name[k['category']], k['name'])))
[{'category': 5, 'name': 'frog'},
 {'category': 5, 'name': 'salamander'},
 {'category': 2, 'name': 'salmon'},
 {'category': 2, 'name': 'tuna '},
 {'category': 2, 'name': 'whale'},
 {'category': 4, 'name': 'mollusk'},
 {'category': 4, 'name': 'octopus'},
 {'category': 4, 'name': 'worms'},
 {'category': 0, 'name': 'dog'},
 {'category': 0, 'name': 'horse'},
 {'category': 0, 'name': 'horse'},
 {'category': 0, 'name': 'kangaroos'},
 {'category': 0, 'name': 'monkey'},
 {'category': 3, 'name': 'alligator'}]
3
Martijn Pieters 15 mars 2019 à 15:26

Imo la structure de votre catégorie est beaucoup trop compliquée - au moins tant que l'uid n'est rien d'autre que l'index, vous pouvez simplement utiliser une liste pour cela:

category = [c['name'] for c in category]
# ['mammals', 'birds', 'fish', 'reptiles', 'invertebrates', 'amphibians']

sorted_animals = sorted(animals, key=lambda k: category[k['category']])

#[{'name': 'frog', 'category': 5}, {'name': 'salamander', 'category': 5}, {'name': 'whale', 'category': 2}, {'name': 'tuna ', 'category': 2}, {'name': 'salmon', 'category': 2}, {'name': 'mollusk', 'category': 4}, {'name': 'worms', 'category': 4}, {'name': 'octopus', 'category': 4}, {'name': 'horse', 'category': 0}, {'name': 'dog', 'category': 0}, {'name': 'horse', 'category': 0}, {'name': 'monkey', 'category': 0}, {'name': 'kangaroos', 'category': 0}, {'name': 'alligator', 'category': 3}]                                                
0
SpghttCd 15 mars 2019 à 16:46