Je sais que pour supprimer une entrée, «clé» de mon dictionnaire d
, en toute sécurité, vous faites:
if d.has_key('key'):
del d['key']
Cependant, je dois supprimer plusieurs entrées du dictionnaire en toute sécurité. Je pensais définir les entrées dans un tuple car je devrai le faire plus d'une fois.
entitiesToREmove = ('a', 'b', 'c')
for x in entitiesToRemove:
if d.has_key(x):
del d[x]
Cependant, je me demandais s'il existe un moyen plus intelligent de le faire?
python
dictionary
dublintech
la source
la source
key in d
est plus pythonique qued.has_key(key)
stackoverflow.com/questions/1323410/has-key-or-infor x in set(d) & entities_to_remove: del d[x]
. Ce ne sera probablement plus efficace que s'ilentities_to_remove
est "grand".Réponses:
Pourquoi pas comme ça:
Une version plus compacte a été fournie par mattbornski en utilisant dict.pop ()
la source
del dict['key1'], dict['key2'], dict['key3']
for key in set(the_dict) & entries:
et de contourner lekey in dict
test.la source
dict.pop()
élimine le besoin de tests d'existence de clés. Excellent..pop()
c'est mauvais et impythonique, et préférerais la réponse acceptée à celle-ci.setdefault
. S'il est mis en œuvre correctement (et je suis sûr que c'est le cas), il ne fait qu'une seule recherche dans la carte de hachage qui est ledict
, au lieu de deux.Utilisation de Dict Comprehensions
où key1 et key2 doivent être supprimés.
Dans l'exemple ci-dessous, les clés "b" et "c" doivent être supprimées et elles sont conservées dans une liste de clés.
la source
O(n)
. L'opération entière estO(mn)
, oùm
est le nombre de clés dans le dict etn
le nombre de clés dans la liste. Je suggère d'utiliser un ensemble à la{key1, key2}
place, si possible.une solution utilise
map
etfilter
fonctionnepython 2
python 3
vous obtenez:
la source
>>> d={"a":1,"b":2,"c":3} >>> l=("a","b","d") >>> map(d.__delitem__, filter(d.__contains__,l)) <map object at 0x10579b9e8> >>> print(d) {'a': 1, 'b': 2, 'c': 3}
list(map(d.__delitem__,filter(d.__contains__,l)))
.... en python 3.4, la fonction de carte renvoie un itérateurdeque(map(...), maxlen=0)
pour éviter de construire une liste de valeurs None; première importation avecfrom collections import deque
Si vous aviez également besoin de récupérer les valeurs des clés que vous supprimez, ce serait un très bon moyen de le faire:
Vous pouvez bien sûr toujours le faire juste pour supprimer les clés de
d
, mais vous créeriez inutilement la liste de valeurs avec la compréhension de liste. Il est également peu clair d'utiliser une compréhension de liste uniquement pour l'effet secondaire de la fonction.la source
valuesRemoved = dict((k, d.pop(k, None)) for k in entitiesToRemove)
et ainsi de suite.J'ai trouvé une solution avec
pop
etmap
La sortie de ceci:
J'ai répondu à cette question si tard simplement parce que je pense que cela aidera à l'avenir si quelqu'un cherche la même chose. Et cela pourrait aider.
Mettre à jour
Le code ci-dessus lancera une erreur si une clé n'existe pas dans le dict.
production:
la source
keys
n'existe pas dansd
- vous devrez d'abord la filtrer.Je n'ai aucun problème avec aucune des réponses existantes, mais j'ai été surpris de ne pas trouver cette solution:
Remarque: je suis tombé sur cette question venant d' ici . Et ma réponse est liée à cette réponse .
la source
Pourquoi pas:
Je ne sais pas ce que vous entendez par «manière plus intelligente». Il existe sûrement d'autres moyens, peut-être avec la compréhension du dictionnaire:
la source
en ligne
la source
Certains tests de synchronisation pour cpython 3 montrent qu'une simple boucle for est le moyen le plus rapide, et il est assez lisible. L'ajout d'une fonction n'entraîne pas non plus beaucoup de surcharge:
résultats timeit (10k itérations):
all(x.pop(v) for v in r) # 0.85
all(map(x.pop, r)) # 0.60
list(map(x.pop, r)) # 0.70
all(map(x.__delitem__, r)) # 0.44
del_all(x, r) # 0.40
<inline for loop>(x, r) # 0.35
Pour les petites itérations, faire cela «en ligne» était un peu plus rapide, à cause de la surcharge de l'appel de fonction. Mais il
del_all
est sûr, réutilisable et plus rapide que toutes les constructions de compréhension et de mappage python.la source
Je pense que l'utilisation du fait que les clés peuvent être traitées comme un ensemble est la meilleure façon si vous êtes sur python 3:
Exemple:
la source
Ce serait bien d'avoir un support complet pour les méthodes set pour les dictionnaires (et non le désordre impie que nous obtenons avec Python 3.9) afin que vous puissiez simplement "supprimer" un ensemble de clés. Cependant, tant que ce n'est pas le cas et que vous disposez d'un dictionnaire volumineux avec potentiellement un grand nombre de clés à supprimer, vous voudrez peut-être en savoir plus sur les performances. J'ai donc créé du code qui crée quelque chose d'assez grand pour des comparaisons significatives: une matrice de 100 000 x 1000, donc 10 000,00 éléments au total.
10 millions d'articles ou plus n'est pas inhabituel dans certains contextes. En comparant les deux méthodes sur ma machine locale, je constate une légère amélioration lors de l'utilisation
map
etpop
, probablement à cause du moins grand nombre d'appels de fonction, mais les deux prennent environ 2,5 secondes sur ma machine. Mais cela ne fait rien par rapport au temps nécessaire pour créer le dictionnaire en premier lieu (55 s), ou en incluant des vérifications dans la boucle. Si cela est probable, il est préférable de créer un ensemble qui est une intersection des clés du dictionnaire et de votre filtre:keys = cells.keys() & keys
En résumé:
del
est déjà fortement optimisé, alors ne vous inquiétez pas de l'utiliser.la source
Je suis en retard à cette discussion mais pour n'importe qui d'autre. Une solution peut être de créer une liste de clés en tant que telle.
Ensuite, utilisez pop () dans une liste de compréhension, ou une boucle for, pour parcourir les touches et les pop une par une.
Le «n / a» est au cas où la clé n'existe pas, une valeur par défaut doit être retournée.
la source
new_dictionary
ressemble beaucoup à une liste;)