Een element uit een woordenboek verwijderen

Is er een manier om een item uit een woordenboek in Python te verwijderen?

Hoe kan ik bovendien een item uit een woordenboek verwijderen om een kopie terug te sturen (d.w.z. het origineel niet wijzigen)?


Antwoord 1, autoriteit 100%

De del-instructieverwijdert een element:

del d[key]

Merk op dat dit het bestaande woordenboek muteert, zodat de inhoud van het woordenboek verandert voor iedereen die een verwijzing naar dezelfde instantie heeft. Om een nieuwwoordenboek terug te geven, maak je een kopie van het woordenboek:

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

De dict()constructor maakt een ondiepe kopie. Zie de module copyom een diepe kopie te maken.


Merk op dat het maken van een kopie voor elk dict del/assignment/etc. betekent dat je van constante tijd naar lineaire tijd gaat, en ook lineaire ruimte gebruikt. Voor kleine dictees is dit geen probleem. Maar als u van plan bent veel kopieën van grote dictaten te maken, wilt u waarschijnlijk een andere gegevensstructuur, zoals een HAMT (zoals beschreven in dit antwoord).


Antwoord 2, autoriteit 18%

popmuteert het woordenboek.

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

Als u het origineel wilt behouden, kunt u het gewoon kopiëren.


3, Autoriteit 5%

Ik denk dat uw oplossing de beste manier is om het te doen. Maar als u een andere oplossing wilt, kunt u een nieuw woordenboek maken met het gebruik van de toetsen van het oude woordenboek zonder uw opgegeven toets, zoals dit:

>>> 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'}

4, Autoriteit 3%

Er zijn veel leuke antwoorden, maar ik wil één ding benadrukken.

U kunt zowel dict.pop()methode en een meer generieke delverklaring om items uit een woordenboek te verwijderen. Ze muten allebei het oorspronkelijke woordenboek, dus je moet een kopie maken (zie details hieronder).

en beide zullen een KeyErrorAls de sleutel die u aan hen geeft, is niet aanwezig in het Woordenboek:

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

en

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

U moet hier voor zorgen:

door het vastleggen van de uitzondering:

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)

en

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)

door een controle uit te voeren:

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

en

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

maar met pop()is er ook een veel beknoptere manier: geef de standaard retourwaarde op:

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

Tenzij u pop()gebruikt om de waarde van een verwijderde sleutel te verkrijgen, mag u alles opgeven, niet noodzakelijk None.
Hoewel het kan zijn dat het gebruik van delmet incheck ietssneller is omdat pop()een functie is met zijn eigen complicaties die overhead veroorzaken. Meestal is dit niet het geval, dus pop()met standaardwaarde is goed genoeg.


Wat de hoofdvraag betreft, je moet een kopie van je woordenboek maken om het originele woordenboek op te slaan en een nieuwe te hebben zonder dat de sleutel wordt verwijderd.

Sommige andere mensen hier stellen voor een volledige (diepe) kopie te maken met copy.deepcopy(), wat misschien een overkill is, een “normale” (ondiepe) kopie, met behulp van copy.copy()of dict.copy(), zou voldoende kunnen zijn. Het woordenboek houdt een verwijzing naar het object bij als een waarde voor een sleutel. Dus wanneer u een sleutel uit een woordenboek verwijdert, wordt deze verwijzing verwijderd, niet het object waarnaar wordt verwezen. Het object zelf kan later automatisch worden verwijderd door de vuilnisman, als er geen andere verwijzingen naar zijn in het geheugen. Het maken van een diepe kopie vereist meer berekeningen in vergelijking met een oppervlakkige kopie, dus het vermindert de codeprestaties door de kopie te maken, geheugen te verspillen en meer werk aan de GC te leveren, soms is een oppervlakkige kopie voldoende.

Als u echter veranderbare objecten als woordenboekwaarden hebt en van plan bent deze later in het geretourneerde woordenboek te wijzigen zonder de sleutel, moet u een diepe kopie maken.

Met ondiepe kopie:

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}

Met diepe kopie:

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}

Antwoord 5, autoriteit 3%

De del-instructieis wat u zoekt . Als je een woordenboek hebt met de naam foo met een sleutel genaamd ‘bar’, kun je ‘bar’ als volgt uit foo verwijderen:

del foo['bar']

Houd er rekening mee dat hierdoor het woordenboek dat wordt geopereerd, permanent wordt gewijzigd. Als je het originele woordenboek wilt behouden, moet je vooraf een kopie maken:

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

De dictoproep maakt een Oppervlakkige kopie. Als je een diepe kopie wilt, gebruik dan copy.deepcopy.

Hier is een methode die u kunt kopiëren & plakken, voor uw gemak:

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

Antwoord 6

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

Resultaat: d = {1: 2, '2': 3}


Antwoord 7

Bel gewoon del d[‘key’].

In productie is het echter altijd een goede gewoonte om te controleren of ‘sleutel’ bestaat in d.

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

Antwoord 8

# mutate/remove with a default
ret_val = body.pop('key', 5)
# no mutation with a default
ret_val = body.get('key', 5)

Antwoord 9

Nee, er is geen andere manier dan

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

Het is echter waarschijnlijk geen goed idee om vaak kopieën te maken van slechts licht gewijzigde woordenboeken, omdat dit resulteert in relatief veel geheugen. Het is meestal beter om het oude woordenboek te loggen (indien nodig) en het dan aan te passen.


Antwoord 10

Hier een ontwerpaanpak op het hoogste niveau:

def eraseElement(d,k):
    if isinstance(d, dict):
        if k in d:
            d.pop(k)
            print(d)
        else:
            print("Cannot find matching key")
    else:
        print("Not able to delete")
exp = {'A':34, 'B':55, 'C':87}
eraseElement(exp, 'C')

Ik ben het passeren van het woordenboek en de sleutel wil ik in mijn functie, valideert als het een woordenboek en als de sleutel in orde is, en als beide bestaan, verwijdert de waarde uit het woordenboek en prenten uit de left-overs.

Output: {'B': 55, 'A': 34}

Hoop dat het helpt!


11

>>> def delete_key(dict, key):
...     del dict[key]
...     return dict
... 
>>> test_dict = {'one': 1, 'two' : 2}
>>> print delete_key(test_dict, 'two')
{'one': 1}
>>>

dit geen foutafhandeling doen, het gaat uit van de sleutel in het dict, je zou willen om te controleren of de eerste en raiseals het niet


12

Hieronder codefragment u zeker zal helpen, heb ik commentaar toegevoegd in elke lijn die u zal helpen bij het begrijpen van de code.

def execute():
   dic = {'a':1,'b':2}
   dic2 = remove_key_from_dict(dic, 'b')  
   print(dict2)           # {'a': 1}
   print(dict)            # {'a':1,'b':2}
def remove_key_from_dict(dictionary_to_use, key_to_delete):
   copy_of_dict = dict(dictionary_to_use)     # creating clone/copy of the dictionary
   if key_to_delete in copy_of_dict :         # checking given key is present in the dictionary
       del copy_of_dict [key_to_delete]       # deleting the key from the dictionary 
   return copy_of_dict                        # returning the final dictionary

of u kunt ook gebruik maken van dict.pop ()

d = {"a": 1, "b": 2}
res = d.pop("c")  # No `KeyError` here
print (res)       # this line will not execute

of de betere aanpak is

res = d.pop("c", "key not found")
print (res)   # key not found
print (d)     # {"a": 1, "b": 2}
res = d.pop("b", "key not found")
print (res)   # 2
print (d)     # {"a": 1}

13

Hier is nog een variatie met behulp van lijst Begreefdy:

original_d = {'a': None, 'b': 'Some'}
d = dict((k,v) for k, v in original_d.iteritems() if v)
# result should be {'b': 'Some'}

De aanpak is gebaseerd op een antwoord van dit bericht:
Efficiënte manier om sleutels te verwijderen met lege snaren van een Dict


14

   species = {'HI': {'1': (1215.671, 0.41600000000000004),
  '10': (919.351, 0.0012),
  '1025': (1025.722, 0.0791),
  '11': (918.129, 0.0009199999999999999),
  '12': (917.181, 0.000723),
  '1215': (1215.671, 0.41600000000000004),
  '13': (916.429, 0.0005769999999999999),
  '14': (915.824, 0.000468),
  '15': (915.329, 0.00038500000000000003),
 'CII': {'1036': (1036.3367, 0.11900000000000001), '1334': (1334.532, 0.129)}}

De volgende code maakt een kopie van DICT speciesen verwijder items die niet in trans_HI

zijn

trans_HI=['1025','1215']
for transition in species['HI'].copy().keys():
    if transition not in trans_HI:
        species['HI'].pop(transition)

15

kan mijn methode proberen. In één regel.

yourList = [{'key':'key1','version':'1'},{'key':'key2','version':'2'},{'key':'key3','version':'3'}]
resultList = [{'key':dic['key']} for dic in yourList if 'key' in dic]
print(resultList)

Other episodes