Considérons le dictionnaire suivant, d:
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
Je veux renvoyer les N premières paires clé: valeur de d (N <= 4 dans ce cas). Quelle est la méthode la plus efficace pour le faire?
Il n’existe pas de clé "n", car une dict
ne se souvient pas des clés insérées en premier.
Vous pouvez cependant obtenir tout _ n paires clé-valeur
n_items = take(n, d.iteritems())
Ceci utilise la mise en oeuvre de take
à partir des recettes itertools
:
from itertools import islice
def take(n, iterable):
"Return first n items of the iterable as a list"
return list(islice(iterable, n))
Regardez le travail en ligne: ideone
Un moyen très efficace de tout récupérer consiste à combiner la compréhension de liste ou de dictionnaire avec le découpage en tranches. Si vous n'avez pas besoin de commander les éléments (vous voulez juste n paires aléatoires), vous pouvez utiliser une compréhension du dictionnaire comme celle-ci:
# Python 2
first2pairs = {k: mydict[k] for k in mydict.keys()[:2]}
# Python 3
first2pairs = {k: mydict[k] for k in list(mydict)[:2]}
Généralement, une compréhension comme celle-ci est toujours plus rapide à exécuter que la boucle équivalente "pour x dans y". De plus, en utilisant .keys () pour créer une liste des clés du dictionnaire et en découpant cette liste, vous évitez de "toucher" à des clés inutiles lorsque vous créez le nouveau dictionnaire.
Si vous n'avez pas besoin des clés (uniquement des valeurs), vous pouvez utiliser une liste de compréhension:
first2vals = [v for v in mydict.values()[:2]]
Si vous avez besoin que les valeurs soient triées en fonction de leurs clés, ce n'est pas beaucoup plus compliqué:
first2vals = [mydict[k] for k in sorted(mydict.keys())[:2]]
ou si vous avez aussi besoin des clés:
first2pairs = {k: mydict[k] for k in sorted(mydict.keys())[:2]}
Les dict
s de Python ne sont pas ordonnés. Il est donc inutile de demander les "premières N" clés.
Le collections.OrderedDict
class est disponible si c'est ce dont vous avez besoin. Vous pouvez efficacement obtenir ses quatre premiers éléments
import itertools
import collections
d = collections.OrderedDict((('foo', 'bar'), (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')))
x = itertools.islice(d.items(), 0, 4)
for key, value in x:
print key, value
itertools.islice
vous permet de prendre paresseux une tranche d’éléments à partir de n’importe quel itérateur. Si vous voulez que le résultat soit réutilisable, vous devez le convertir en liste ou quelque chose du genre, comme ceci:
x = list(itertools.islice(d.items(), 0, 4))
foo = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6}
iterator = iter(foo.items())
for i in range(3):
print(next(iterator))
Fondamentalement, tournez la vue (dict_items) en itérateur, puis répétez-la avec next ().
Je ne l'ai pas vu ici. Ne sera pas commandé mais le plus simple syntaxiquement si vous avez juste besoin de prendre quelques éléments d'un dictionnaire.
n = 2
{key:value for key,value in d.items()[0:n]}
Voir PEP 0265 sur le tri des dictionnaires. Ensuite, utilisez le code itérable précité.
Si vous avez besoin de plus d'efficacité dans les paires clé-valeur triées. Utilisez une structure de données différente. C’est-à-dire un système qui conserve l’ordre trié et les associations clé-valeur.
Par exemple.
import bisect
kvlist = [('a', 1), ('b', 2), ('c', 3), ('e', 5)]
bisect.insort_left(kvlist, ('d', 4))
print kvlist # [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)]
Cela dépend de ce qui est "le plus efficace" dans votre cas.
Si vous voulez juste un échantillon semi-aléatoire d'un énorme dictionnaire foo
, utilisez foo.iteritems()
et prenez-en autant de valeurs que nécessaire, c'est une opération lazy qui évite la création d'une liste explicite de clés ou d'éléments.
Si vous devez d’abord trier les clés, il n’est pas possible d’utiliser une fonction comme keys = foo.keys(); keys.sort()
ou sorted(foo.iterkeys())
, vous devrez créer une liste explicite de clés. Puis coupez ou parcourez la première N keys
.
BTW pourquoi vous souciez-vous de la manière «efficace»? Avez-vous profilé votre programme? Si ce n'est pas le cas, utilisez d'abord le chemin évident et facile à comprendre . Il y a de fortes chances que cela se passe plutôt bien sans goulot d'étranglement.
Pour Python 3 et supérieur, Pour sélectionner les n premières paires
n=4
firstNpairs = {k: Diction[k] for k in list(Diction.keys())[:n]}
envisager un dict
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
from itertools import islice
n = 3
list(islice(d.items(),n))
islice fera l'affaire :) espérons que cela aide!
ajoutez simplement une réponse en utilisant Zip,
{k: d[k] for k, _ in Zip(d, range(n))}
Vous pouvez aborder ce problème de plusieurs manières. Si l'ordre est important, vous pouvez le faire:
for key in sorted(d.keys()):
item = d.pop(key)
Si l'ordre ne vous concerne pas, vous pouvez le faire:
for i in range(4):
item = d.popitem()
Le dictionnaire ne conserve aucun ordre. Par conséquent, avant de choisir les N premières paires de valeurs-clés, nous allons le trier.
import operator
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4}
d=dict(sorted(d.items(),key=operator.itemgetter(1),reverse=True))
#itemgetter(0)=sort by keys, itemgetter(1)=sort by values
Maintenant, nous pouvons récupérer les 'N' éléments les plus importants, en utilisant la structure de la méthode comme ceci:
def return_top(elements,dictionary_element):
'''Takes the dictionary and the 'N' elements needed in return
'''
topers={}
for h,i in enumerate(dictionary_element):
if h<elements:
topers.update({i:dictionary_element[i]})
return topers
pour obtenir les 2 meilleurs éléments, utilisez simplement cette structure:
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4}
d=dict(sorted(d.items(),key=operator.itemgetter(1),reverse=True))
d=return_top(2,d)
print(d)
Cela peut ne pas être très élégant, mais fonctionne pour moi:
d = {'a': 3, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
x= 0
for key, val in d.items():
if x == 2:
break
else:
x += 1
# Do something with the first two key-value pairs