2016-10-31 1 views
1

Donc, j'ai un dictionnaire ordonné, et il a une pile de paires clé/valeur. Je peux les extraire avec la méthode items(). Mais que se passe-t-il si je veux seulement en sélectionner QUELQUES?Champs de sous-ensemble d'une commande ordered?

>>> import collections 
>>> d = collections.OrderedDict({'banana': 3, 'apple': 4, 'pear': 1,'orange': 2}) 
>>> d.items() 
[('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)] 

Et si je voulais juste des pommes et des bananes?

Y a-t-il un moyen de spécifier les touches que je veux?

>>> d['apple','banana'] <-- does not work 

J'envisage d'utiliser une compréhension de la liste à la fin de filtrer les résultats, mais il semble en désordre et je l'espère, il y a une meilleure façon.

+0

Que voulez-vous 'd ['apple', 'banana']' produire? – martineau

+0

Une liste de tuples ou de paires clé/valeur, identique à .items(). – Exie

Répondre

0

Vous finirez probablement par utiliser une compréhension de liste d'une manière ou d'une autre. Voici un moyen d'enterrer la compréhension de la liste dans une implémentation de la méthode:

from collections import OrderedDict 

class MultOrderedDict(OrderedDict): 
    def items(self, *items): 
     all = super(MultOrderedDict, self).items() 
     if not items: 
      return all 
     return type(self)((key, value) for (key, value) in all if key in items).items() 

Avec cette définition de classe (en supposant qu'il est en multorddict.py) vous pouvez faire quelque chose comme ceci:

>>> from multorddict import MultOrderedDict 
>>> mod = MultOrderedDict(banana=3, apple=4, pear=1, orange=2) 
>>> mod.items() 
[('orange', 2), ('pear', 1), ('apple', 4), ('banana', 3)] 
>>> mod.items('apple','banana') 
[('apple', 4), ('banana', 3)] 
>>> 

Cette approche change la sémantique de la méthode items, ce qui pourrait ne pas être une bonne chose.

+0

Cela ne renvoie pas une liste de tuples ou de paires clé/valeur, comme le fait 'items()'. Il est également infiniment récurrent quand 'mod ['apple', 'banana']' est exécuté. – martineau

+0

D'accord, je n'ai pas testé mon implémentation initiale dans python2 (elle n'a pas le même problème dans python3). Je voudrais simplement supprimer la réponse si elle n'avait pas été acceptée, mais je l'ai reformulée pour remplacer "items" plutôt que "__getitem__". En fin de compte, il est plus logique de se familiariser avec la compréhension des listes et de les utiliser directement. –

1

Je ne connais pas de méthode qui existe mais il pourrait être utile de créer une méthode générique si c'est quelque chose que vous avez à faire à travers votre base de code. Peut-être quelque chose comme

>>> specific_dict_items = lambda d, l: [(key, d.get(key, '')) for key in l] 
>>> specific_dict_items({1:1, 2:2, 3:3, 4:4, 5:5}, [1, 3, 5, 7]) 
[(1, 1), (3, 3), (5, 5), (7, '')] 
3

Vous pouvez définir une seule ligne pour le faire:

>>> import collections 
>>> d = collections.OrderedDict({'banana': 3, 'apple': 4, 'pear': 1,'orange': 2}) 
>>> d.items() 
[('orange', 2), ('pear', 1), ('banana', 3), ('apple', 4)] 
>>> 
>>> subset = lambda d, *keys: [(key, d[key]) for key in keys] 
>>> subset(d, 'apple', 'banana') 
[('apple', 4), ('banana', 3)] 

En prime, il fonctionne aussi avec dict régulièrement des objets.