Question Supprimer un élément d'un dictionnaire


Est-il possible de supprimer un élément d'un dictionnaire en Python?

De plus, comment puis-je supprimer un élément d'un dictionnaire pour renvoyer une copie (c'est-à-dire ne pas modifier l'original)?


842
2018-04-30 21:20


origine


Réponses:


le del déclaration supprime un élément:

del d[key]

Cependant, cela mute le dictionnaire existant de sorte que le contenu du dictionnaire change pour quelqu'un d'autre qui a une référence à la même instance. Pour retourner un Nouveau dictionnaire, faites une copie du dictionnaire:

def removekey(d, key):
    r = dict(d)
    del r[key]
    return r

le dict() constructeur fait un copie superficielle. Pour faire une copie profonde, voir le copy module.


Notez que faire une copie pour chaque dict del/ affectation / etc signifie que vous allez du temps constant au temps linéaire, et aussi en utilisant l'espace linéaire. Pour les petits dicts, ce n'est pas un problème. Mais si vous prévoyez de faire beaucoup de copies de grands dicts, vous voulez probablement une structure de données différente, comme un HAMT (comme décrit dans cette réponse).


1184
2018-04-30 21:25



pop mute le dictionnaire.

 >>>lol = {"hello":"gdbye"}
 >>>lol.pop("hello")
    'gdbye'
 >>> lol
     {}

Si vous voulez conserver l'original, vous pouvez simplement le copier.


130
2018-03-21 16:22



Je pense que votre solution est la meilleure façon de le faire. Mais si vous voulez une autre solution, vous pouvez créer un nouveau dictionnaire en utilisant les clés du vieux dictionnaire sans inclure votre clé spécifiée, comme ceci:

>>> a
{0: 'zero', 1: 'one', 2: 'two', 3: 'three'}
>>> {i:a[i] for i in a if i!=0}
{1: 'one', 2: 'two', 3: 'three'}

55
2018-04-30 21:26



le del déclaration est ce que vous cherchez. Si vous avez un dictionnaire nommé foo avec une clé appelée 'bar', vous pouvez supprimer 'bar' de foo comme ceci:

del foo['bar']

Notez que cela modifie en permanence le dictionnaire en cours d'exploitation. Si vous voulez conserver le dictionnaire original, vous devrez en créer une copie à l'avance:

>>> foo = {'bar': 'baz'}
>>> fu = dict(foo)
>>> del foo['bar']
>>> print foo
{}
>>> print fu
{'bar': 'baz'}

le dict appel fait une copie superficielle. Si vous voulez une copie profonde, utilisez copy.deepcopy.

Voici une méthode que vous pouvez copier et coller, pour votre commodité:

def minus_key(key, dictionary):
    shallow_copy = dict(dictionary)
    del shallow_copy[key]
    return shallow_copy

47
2018-04-30 21:23



d = {1: 2, '2': 3, 5: 7}
del d[5]
print 'd = ', d

Résultat: d = {1: 2, '2': 3}


16
2018-04-30 21:24



Il y a beaucoup de bonnes réponses, mais je tiens à souligner une chose.

Vous pouvez utiliser les deux dict.pop() méthode et un plus générique del déclaration supprimer des éléments d'un dictionnaire Ils ont tous deux muter le dictionnaire original, vous devez donc faire une copie (voir les détails ci-dessous).

Et les deux vont soulever un KeyError si la clé que vous leur fournissez n'est pas présente dans le dictionnaire:

key_to_remove = "c"
d = {"a": 1, "b": 2}
del d[key_to_remove]  # Raises `KeyError: 'c'`

et

key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove)  # Raises `KeyError: 'c'`

Vous devez prendre soin de cela:

en capturant l'exception:

key_to_remove = "c"
d = {"a": 1, "b": 2}
try:
    del d[key_to_remove]
except KeyError as ex:
    print("No such key: '%s'" % ex.message)

et

key_to_remove = "c"
d = {"a": 1, "b": 2}
try:
    d.pop(key_to_remove)
except KeyError as ex:
    print("No such key: '%s'" % ex.message)

en effectuant une vérification:

key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
    del d[key_to_remove]

et

key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
    d.pop(key_to_remove)

mais avec pop() il y a aussi un moyen beaucoup plus concis - fournir la valeur de retour par défaut:

key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove, None)  # No `KeyError` here

Sauf si vous utilisez pop() pour obtenir la valeur d'une clé supprimée, vous pouvez fournir quelque chose, pas nécessaire None. Bien que cela puisse être cela en utilisant del avec in vérifier est légèrement plus rapide en raison de pop() être une fonction avec ses propres complications causant des frais généraux. Habituellement, ce n'est pas le cas, alors pop() avec la valeur par défaut est assez bon.


Comme pour la question principale, vous devrez faire une copie de votre dictionnaire, pour enregistrer le dictionnaire original et en avoir un nouveau sans que la clé soit supprimée.

D'autres personnes ici suggèrent de faire une copie complète (profonde) avec copy.deepcopy(), qui pourrait être une surdicécité, une copie "normale" (peu profonde), en utilisant copy.copy() ou dict.copy(), pourrait être suffisant. Le dictionnaire conserve une référence à l'objet en tant que valeur pour une clé. Ainsi, lorsque vous supprimez une clé d'un dictionnaire, cette référence est supprimée, pas l'objet référencé. L'objet lui-même peut être retiré plus tard automatiquement par le garbage collector, s'il n'y a pas d'autres références pour cela dans la mémoire. Faire une copie en profondeur nécessite plus de calculs par rapport à une copie superficielle, donc cela diminue la performance du code en faisant la copie, en gaspillant de la mémoire et en fournissant plus de travail au GC, parfois une copie superficielle suffit.

Toutefois, si vous avez des objets modifiables en tant que valeurs de dictionnaire et prévoyez de les modifier plus tard dans le dictionnaire renvoyé sans la clé, vous devez effectuer une copie en profondeur.

Avec une copie superficielle:

def get_dict_wo_key(dictionary, key):
    """Returns a **shallow** copy of the dictionary without a key."""
    _dict = dictionary.copy()
    _dict.pop(key, None)
    return _dict


d = {"a": [1, 2, 3], "b": 2, "c": 3}
key_to_remove = "c"

new_d = get_dict_wo_key(d, key_to_remove)
print(d)  # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d)  # {"a": [1, 2, 3], "b": 2}
new_d["a"].append(100)
print(d)  # {"a": [1, 2, 3, 100], "b": 2, "c": 3}
print(new_d)  # {"a": [1, 2, 3, 100], "b": 2}
new_d["b"] = 2222
print(d)  # {"a": [1, 2, 3, 100], "b": 2, "c": 3}
print(new_d)  # {"a": [1, 2, 3, 100], "b": 2222}

Avec copie profonde:

from copy import deepcopy


def get_dict_wo_key(dictionary, key):
    """Returns a **deep** copy of the dictionary without a key."""
    _dict = deepcopy(dictionary)
    _dict.pop(key, None)
    return _dict


d = {"a": [1, 2, 3], "b": 2, "c": 3}
key_to_remove = "c"

new_d = get_dict_wo_key(d, key_to_remove)
print(d)  # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d)  # {"a": [1, 2, 3], "b": 2}
new_d["a"].append(100)
print(d)  # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d)  # {"a": [1, 2, 3, 100], "b": 2}
new_d["b"] = 2222
print(d)  # {"a": [1, 2, 3], "b": 2, "c": 3}
print(new_d)  # {"a": [1, 2, 3, 100], "b": 2222}

16
2017-09-21 19:52



Appelez simplement del d ['key'].

Cependant, en production, il est toujours recommandé de vérifier si «clé» existe dans d.

if 'key' in d:
    del d['key']

12
2018-03-02 13:39



Non, il n'y a pas d'autre moyen que

def dictMinus(dct, val):
   copy = dct.copy()
   del copy[val]
   return copy

Cependant, créer souvent des copies de dictionnaires légèrement modifiés n'est probablement pas une bonne idée car cela entraînera des demandes de mémoire relativement importantes. Il est généralement préférable d'enregistrer le vieux dictionnaire (si nécessaire), puis de le modifier.


6
2018-04-30 21:27