Usuwanie elementu ze słownika
Czy istnieje sposób na usunięcie elementu ze słownika w Pythonie?
DODATKOWO, Jak mogę usunąć element ze słownika, aby zwrócić kopię (tzn. nie modyfikować oryginału)?
14 answers
The del
Instrukcja usuwa element:
del d[key]
Jednakże powoduje to mutację istniejącego słownika, więc zawartość słownika zmienia się dla każdego, kto ma odniesienie do tej samej instancji. Aby zwrócić Nowy słownik , wykonaj kopię słownika:
def removekey(d, key):
r = dict(d)
del r[key]
return r
Konstruktor dict()
tworzypłytką kopię . Aby zrobić głęboką kopię, zobacz copy
moduł .
Zauważ, że tworzenie kopii dla każdego dict del
/assignment / etc. oznacza przejście od czasu stałego do czasu liniowego, a także użycie przestrzeni liniowej. Dla małych dictów nie jest to problem. Ale jeśli planujesz zrobić wiele kopii dużych dictów, prawdopodobnie potrzebujesz innej struktury danych, jak HAMT(jak opisano w ta odpowiedź ).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-15 01:27:47
pop
mutuje słownik.
>>>lol = {"hello":"gdbye"}
>>>lol.pop("hello")
'gdbye'
>>> lol
{}
Jeśli chcesz zachować oryginał, możesz go skopiować.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-14 11:08:00
Myślę, że Twoje rozwiązanie jest najlepszym sposobem, aby to zrobić. Ale jeśli chcesz innego rozwiązania, możesz utworzyć nowy słownik za pomocą kluczy ze starego słownika bez włączania określonego klucza, jak to:
>>> 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'}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-30 21:26:40
Oświadczenie del jest tym, czego szukasz. Jeśli masz Słownik o nazwie foo z kluczem o nazwie 'bar', możesz usunąć 'bar' z foo w następujący sposób:
del foo['bar']
Zauważ, że to trwale modyfikuje słownik, na którym jest operowany. Jeśli chcesz zachować oryginalny słownik, musisz wcześniej utworzyć kopię:
>>> foo = {'bar': 'baz'}
>>> fu = dict(foo)
>>> del foo['bar']
>>> print foo
{}
>>> print fu
{'bar': 'baz'}
The dict
call robi płytką kopię. Jeśli chcesz mieć głęboką kopię, użyj copy.deepcopy
.
Oto metoda, którą możesz skopiować & wklej, dla Twojej wygody:
def minus_key(key, dictionary):
shallow_copy = dict(dictionary)
del shallow_copy[key]
return shallow_copy
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-30 14:27:40
Jest wiele ładnych odpowiedzi, ale chcę podkreślić jedną rzecz.
Możesz użyć obu dict.pop()
metoda i bardziej ogólny del
oświadczenie , aby usunąć elementy ze słownika. Oba mutują oryginalny Słownik, więc musisz zrobić kopię(zobacz szczegóły poniżej).
I oboje podniosą KeyError
jeśli klucz, który im podajesz, nie jest obecny w słowniku:
key_to_remove = "c"
d = {"a": 1, "b": 2}
del d[key_to_remove] # Raises `KeyError: 'c'`
I
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove) # Raises `KeyError: 'c'`
Ty trzeba się tym zająć:
Przez przechwycenie wyjątku:
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)
I
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)
Wykonując kontrolę:
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
del d[key_to_remove]
I
key_to_remove = "c"
d = {"a": 1, "b": 2}
if key_to_remove in d:
d.pop(key_to_remove)
Ale z pop()
istnieje również znacznie bardziej zwięzły sposób-podaj domyślną wartość zwracaną:
key_to_remove = "c"
d = {"a": 1, "b": 2}
d.pop(key_to_remove, None) # No `KeyError` here
Jeśli nie użyjesz pop()
, aby uzyskać wartość usuwanego klucza, możesz podać cokolwiek, co nie jest konieczne None
.
Choć może być tak, że użycie del
z in
check jest nieco szybciej ze względu na to, że pop()
jest funkcją z własnymi komplikacjami powodującymi nadmiarowość. Zazwyczaj tak nie jest, więc {[12] } z wartością domyślną jest wystarczająco dobra.
Jeśli chodzi o główne pytanie, musisz zrobić kopię swojego słownika, aby zapisać oryginalny słownik i mieć nowy bez usuwania klucza.
Niektórzy tutaj sugerują zrobienie pełnej (głębokiej) kopii z copy.deepcopy()
, co może być przesadą, "normalnym" (płytkim) Kopiuj, używając copy.copy()
lub dict.copy()
, może wystarczy. Słownik zachowuje odniesienie do obiektu jako wartość klucza. Więc kiedy usuniesz klucz ze słownika, to odniesienie zostanie usunięte, a nie obiekt, do którego się odwołuje. Sam obiekt może zostać później automatycznie usunięty przez garbage collector, jeśli w pamięci nie ma innych odniesień do niego. Wykonanie głębokiej kopii wymaga więcej obliczeń w porównaniu z płytką kopią, więc zmniejsza wydajność kodu poprzez wykonanie kopiowanie, marnowanie pamięci i dostarczanie większej ilości pracy do GC, czasem wystarczy płytka Kopia.
Jeśli jednak jako wartości słownika masz zmienne obiekty i planujesz je później zmodyfikować w zwracanym słowniku bez klucza, musisz wykonać głęboką kopię.
Z płytką kopią:
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}
Z głęboką kopią:
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}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-23 05:15:18
d = {1: 2, '2': 3, 5: 7}
del d[5]
print 'd = ', d
Wynik: d = {1: 2, '2': 3}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-30 21:24:48
Po prostu wywołaj del D ['klucz'].
Jednak w produkcji zawsze dobrą praktyką jest sprawdzanie, czy "klucz" istnieje w d.
if 'key' in d:
del d['key']
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-02 13:39:10
Nie, Nie ma innej drogi niż
def dictMinus(dct, val):
copy = dct.copy()
del copy[val]
return copy
Jednak często tworzenie kopii tylko nieznacznie zmienionych słowników prawdopodobnie nie jest dobrym pomysłem, ponieważ spowoduje to stosunkowo duże zapotrzebowanie na pamięć. Zwykle lepiej jest zalogować się do starego słownika(jeśli jest to konieczne), a następnie zmodyfikować go.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-30 21:27:32
>>> def delete_key(dict, key):
... del dict[key]
... return dict
...
>>> test_dict = {'one': 1, 'two' : 2}
>>> print delete_key(test_dict, 'two')
{'one': 1}
>>>
To nie robi żadnej obsługi błędów, zakłada, że klucz jest w dict, możesz chcieć to sprawdzić najpierw i raise
jeśli nie
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-30 21:26:25
... Jak mogę usunąć element ze słownika, aby zwrócić kopię (tzn. nie modyfikować oryginału)?
A {[1] } jest niewłaściwą strukturą danych do tego celu.
Jasne, kopiowanie dict i wyskakiwanie z kopii działa, podobnie jak budowanie nowego dict ze zrozumieniem, ale wszystko to kopiowanie wymaga czasu-zastąpiłeś operację czasową stałą na czas liniowy. Wszystkie te kopie naraz zajmują przestrzeń liniową na jedną kopię.
Inne struktury danych, takie jak hash array mapped tries , są zaprojektowane do tego typu przypadków użycia: dodanie lub usunięcie elementu zwraca kopię w czasie logarytmicznym, dzieląc większość jego przechowywania z oryginalnym.1
Oczywiście są pewne wady. Wydajność jest logarytmiczna, a nie stała (choć z dużą podstawą, Zwykle 32-128). I chociaż można uczynić API niemutujące identycznym z dict
, API" mutujące " jest oczywiście inne. A przede wszystkim nie ma baterii HAMT w zestawie z Pythonem.2
The pyrsistent
Biblioteka jest dość solidną implementacją opartych na HAMT dict-replacements (i różnych innych typów) dla Pythona. Posiada nawet sprytne evolver API do przenoszenia istniejącego mutującego kodu na trwały kod tak płynnie, jak to możliwe. Ale jeśli chcesz być szczery o zwracaniu kopii, a nie mutacji, po prostu użyj tego w następujący sposób:
>>> from pyrsistent import m
>>> d1 = m(a=1, b=2)
>>> d2 = d1.set('c', 3)
>>> d3 = d1.remove('a')
>>> d1
pmap({'a': 1, 'b': 2})
>>> d2
pmap({'c': 3, 'a': 1, 'b': 2})
>>> d3
pmap({'b': 2})
That d3 = d1.remove('a')
is exactly what pytanie zadaje pytanie.
Jeśli masz zmienne struktury danych, takie jak dict
i list
osadzone w pmap
, nadal będziesz mieć problemy z aliasingiem-możesz to naprawić tylko, przechodząc niezmiennie w dół, osadzając pmap
s I pvector
s.
1. HAMTs stały się również popularne w językach takich jak Scala, Clojure, Haskell, ponieważ grają bardzo ładnie z programowaniem bez blokady i pamięcią transakcyjną oprogramowania, ale żaden z nich nie jest bardzo istotny w Python.
2. W rzeczywistości istnieje HAMT w stdlib, używany w implementacji contextvars
. wcześniej wycofany PEP wyjaśnia dlaczego. ale jest to ukryty szczegół implementacji biblioteki, a nie Typ kolekcji publicznej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-15 01:33:06
Tutaj podejście do projektowania na najwyższym poziomie:
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')
Przekazuję słownik i klucz, który chcę do mojej funkcji, sprawdza, czy jest to słownik i czy klucz jest w porządku, a jeśli oba istnieją, usuwa wartość ze słownika i wypisuje lewe przejścia.
Wyjście: {'B': 55, 'A': 34}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-15 15:50:44
Nice one-liner, aby sprawdzić, czy klucz jest obecny, usunąć go, zwrócić wartość, lub domyślne:
ret_val = ('key' in body and body.pop('key')) or 5
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-05 20:40:53
Poniższy fragment kodu zdecydowanie ci pomoże, dodałem komentarze w każdej linii, które pomogą Ci w zrozumieniu kodu.
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
Lub możesz również użyć dict.pop ()
d = {"a": 1, "b": 2}
res = d.pop("c") # No `KeyError` here
print (res) # this line will not execute
Or the better approach 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}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-30 20:10:01
Oto kolejna odmiana wykorzystująca rozumienie listy:
original_d = {'a': None, 'b': 'Some'}
d = dict((k,v) for k, v in original_d.iteritems() if v)
# result should be {'b': 'Some'}
Podejście opiera się na odpowiedzi z tego postu: skuteczny sposób usuwania kluczy z pustymi łańcuchami z dict
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:24