supposons que j'ai des quantités de fruits de différentes couleurs, par exemple 24 bananes bleues, 12 pommes vertes, 0 fraises bleues et ainsi de suite. Je voudrais les organiser dans une structure de données en Python qui permet une sélection et un tri faciles. Mon idée était de les mettre dans un dictionnaire avec des tuples comme clés, par exemple,
{ ('banana', 'blue' ): 24,
('apple', 'green'): 12,
('strawberry','blue' ): 0,
...
}
ou même des dictionnaires, par exemple,
{ {'fruit': 'banana', 'color': 'blue' }: 24,
{'fruit': 'apple', 'color': 'green'}: 12,
{'fruit': 'strawberry','color': 'blue' }: 0,
...
}
J'aimerais récupérer une liste de tous les fruits bleus, ou des bananes de toutes les couleurs, par exemple, ou trier ce dictionnaire par le nom du fruit. Existe-t-il des moyens de le faire de manière propre?
Il se peut que les dictionnaires avec des tuples comme clés ne soient pas la bonne façon de gérer cette situation.
Toutes les suggestions sont les bienvenues!
Réponses:
Personnellement, l'une des choses que j'aime chez python est la combinaison tuple-dict. Ce que vous avez ici est en fait un tableau 2d (où x = nom du fruit et y = couleur), et je suis généralement un partisan du dict des tuples pour implémenter des tableaux 2d, du moins quand quelque chose comme
numpy
ou une base de données n'est pas plus approprié . Bref, je pense que vous avez une bonne approche.Notez que vous ne pouvez pas utiliser de dictionnaires comme clés dans un dict sans faire un travail supplémentaire, ce n'est donc pas une très bonne solution.
Cela dit, vous devriez également considérer namedtuple () . De cette façon, vous pourriez faire ceci:
Vous pouvez maintenant utiliser votre dict de comptage de fruits:
Autres astuces:
En écho à chmullig, pour obtenir une liste de toutes les couleurs d'un fruit, il faudrait filtrer les clés, c'est-à-dire
la source
name='banana'
?bananas = filter(lambda fruit: fruit.name=='banana', fruits)
-à- dire oubananas = [fruit for fruit in fruits if fruit.name=='banana']
. C'est une façon dont les dictionnaires imbriqués sont potentiellement plus efficaces; tout dépend de la manière dont vous prévoyez d'utiliser les données.count
Votre meilleure option sera de créer une structure de données simple pour modéliser ce que vous avez. Ensuite, vous pouvez stocker ces objets dans une liste simple et les trier / les récupérer comme vous le souhaitez.
Pour ce cas, j'utiliserais la classe suivante:
Ensuite, vous pouvez simplement construire des instances "Fruit" et les ajouter à une liste, comme indiqué de la manière suivante:
La liste simple
fruits
sera beaucoup plus facile, moins déroutante et mieux entretenue.Quelques exemples d'utilisation:
Toutes les sorties ci-dessous sont le résultat après l'exécution de l'extrait de code donné suivi de:
Liste non triée:
Affiche:
Trié par ordre alphabétique par nom:
Affiche:
Trié par quantité:
Affiche:
Où couleur == rouge:
Affiche:
la source
Base de données, dict de dictionnaires, dictionnaire de liste de dictionnaires, tuple nommé (c'est une sous-classe), sqlite, redondance ... Je n'en croyais pas mes yeux. Quoi d'autre ?
Ouais! j'ai pensé
Donc, à mon avis, une liste de tuples suffit largement:
résultat
la source
Un dictionnaire n'est probablement pas ce que vous devriez utiliser dans ce cas. Une bibliothèque plus complète serait une meilleure alternative. Probablement une vraie base de données. Le plus simple serait sqlite . Vous pouvez garder le tout en mémoire en passant la chaîne ': memory:' au lieu d'un nom de fichier.
Si vous souhaitez continuer sur ce chemin, vous pouvez le faire avec les attributs supplémentaires de la clé ou de la valeur. Cependant, un dictionnaire ne peut pas être la clé d'un autre dictionnaire, mais un tuple le peut. Les documents expliquent ce qui est autorisé. Il doit s'agir d'un objet immuable, qui comprend des chaînes, des nombres et des tuples qui ne contiennent que des chaînes et des nombres (et plus de tuples ne contenant que ces types de manière récursive ...).
Vous pouvez faire votre premier exemple avec
d = {('apple', 'red') : 4}
, mais il sera très difficile de rechercher ce que vous voulez. Vous auriez besoin de faire quelque chose comme ceci:la source
Avec des clés comme tuples, il vous suffit de filtrer les clés avec un deuxième composant donné et de le trier:
Le tri fonctionne parce que les tuples ont un ordre naturel si leurs composants ont un ordre naturel.
Les clés étant des objets à part entière, il suffit de filtrer par
k.color == 'blue'
.Vous ne pouvez pas vraiment utiliser les dictionnaires comme clés, mais vous pouvez créer une classe la plus simple comme
class Foo(object): pass
et y ajouter des attributs à la volée:Ces instances peuvent servir de clés dict, mais attention à leur mutabilité!
la source
Vous pourriez avoir un dictionnaire où les entrées sont une liste d'autres dictionnaires:
Production:
Edit: Comme l'a souligné eumiro, vous pouvez utiliser un dictionnaire de dictionnaires:
Production:
la source
Ce type de données est efficacement extrait d'une structure de données de type Trie. Il permet également un tri rapide. L'efficacité de la mémoire n'est peut-être pas si bonne.
Un trie traditionnel stocke chaque lettre d'un mot comme un nœud dans l'arbre. Mais dans votre cas, votre «alphabet» est différent. Vous stockez des chaînes au lieu de caractères.
cela pourrait ressembler à ceci:
voir ce lien: trie en python
la source
Vous souhaitez utiliser deux touches indépendamment, vous avez donc deux choix:
Stockez les données de manière redondante avec deux dictionnaires comme
{'banana' : {'blue' : 4, ...}, .... }
et{'blue': {'banana':4, ...} ...}
. Ensuite, la recherche et le tri sont faciles, mais vous devez vous assurer de modifier les dicts ensemble.Stockez-le juste un dict, puis écrivez des fonctions qui les itèrent par exemple:
la source