Jak mogę dodać nowe klucze do słownika?

2617

Czy można dodać klucz do słownika Python po jego utworzeniu?

Wydaje się, że nie ma .add()metody.

lfaraone
źródło
25
Jeśli są tutaj próbuje dowiedzieć się, jak dodać klucz i zwraca nowy słownik, można to zrobić na python3.5 +: {**mydict, 'new_key': new_val}.
cs95,
Albo użyj przyjętej odpowiedzi: d ['mynewkey'] = 'mynewvalue' lub możesz użyć val = d.setdefault ('mynewkey', 'mynewvalue')
Ol 'Dawg

Odpowiedzi:

3399
d = {'key': 'value'}
print(d)
# {'key': 'value'}
d['mynewkey'] = 'mynewvalue'
print(d)
# {'key': 'value', 'mynewkey': 'mynewvalue'}
Paolo Bergantino
źródło
107
Wyjaśnienie jest następujące: tworzysz nową parę klucz \ wartość w słowniku, przypisując wartość do tego klucza. Jeśli klucz nie istnieje, jest dodawany i wskazuje na tę wartość. Jeśli istnieje, bieżąca wartość, na którą wskazuje, jest zastępowana.
R. Navega
9
Jaka jest różnica między tym a .update()metodą? Który jest lepszy kiedy?
hegash
13
@hegash d[key]=valskładnia, ponieważ jest krótsza i może obsługiwać dowolny obiekt jako klucz (o ile jest możliwy do skrótu), i ustawia tylko jedną wartość, podczas gdy .update(key1=val1, key2=val2)jest ładniejsza, jeśli chcesz ustawić wiele wartości jednocześnie, o ile klucze są ciągami (ponieważ kwargi są konwertowane na ciągi). dict.updatemogę również wziąć inny słownik, ale osobiście wolę nie tworzyć nowego słownika w celu aktualizacji innego.
bgusach
spróbuj, oto przykład: repl.it/@SmaMa/Add-key-to-dict
Sma Ma
jak mogę dodać element do zagnieżdżonego nagrania. Jak php$foo[ ] = [ . . . . ]
Juan-Kabbali
1041

Aby dodać wiele kluczy jednocześnie, użyj dict.update():

>>> x = {1:2}
>>> print(x)
{1: 2}

>>> d = {3:4, 5:6, 7:8}
>>> x.update(d)
>>> print(x)
{1: 2, 3: 4, 5: 6, 7: 8}

W przypadku dodania jednego klucza zaakceptowana odpowiedź ma mniejszy narzut obliczeniowy.

Peter Mortensen
źródło
13
jest to bardzo nieefektywne, aby utworzyć słownik, aby zaktualizować tylko jeden klucz. Zrób to tylko, jeśli masz więcej niż 1 klucz (może istnieć próg, powyżej którego lepiej jest utworzyć dyktando)
Jean-François Fabre
10
@ Jean-FrançoisFabre To jest przykładowy kod. Naprawdę nie powinieneś traktować odpowiedzi jako obejmującej wszystkie przypadki.
Robert Brisita
1
daje błędne wrażenie, że jest to preferowany sposób dodania jednego klucza.
Jean-François Fabre
@ Jean-FrançoisFabre Ponieważ porządkowanie nagrań jest zagwarantowane w Pythonie 3.7+ (i dostarczane w 3.6+) , może to być preferowany sposób dodawania jednego klucza, gdy kolejność jest ważna .
ingyhere
jeśli tworzysz inny klucz jak x[-1] = 44w -1wartości jest w końcu też. W każdym razie odpowiedź została zredagowana i jest teraz znacznie lepsza. Aktualizacja za pomocą słownika jest dobra, gdy prawdopodobne jest, że zawiera wiele elementów.
Jean-François Fabre
926

Chcę skonsolidować informacje o słownikach Python:

Tworzenie pustego słownika

data = {}
# OR
data = dict()

Tworzenie słownika z wartościami początkowymi

data = {'a': 1, 'b': 2, 'c': 3}
# OR
data = dict(a=1, b=2, c=3)
# OR
data = {k: v for k, v in (('a', 1), ('b',2), ('c',3))}

Wstawianie / aktualizowanie pojedynczej wartości

data['a'] = 1  # Updates if 'a' exists, else adds 'a'
# OR
data.update({'a': 1})
# OR
data.update(dict(a=1))
# OR
data.update(a=1)

Wstawianie / aktualizowanie wielu wartości

data.update({'c':3,'d':4})  # Updates 'c' and adds 'd'

Tworzenie scalonego słownika bez modyfikowania oryginałów

data3 = {}
data3.update(data)  # Modifies data3, not data
data3.update(data2)  # Modifies data3, not data2

Usuwanie pozycji ze słownika

del data[key]  # Removes specific element in a dictionary
data.pop(key)  # Removes the key & returns the value
data.clear()  # Clears entire dictionary

Sprawdź, czy klucz jest już w słowniku

key in data

Iteruj parami w słowniku

for key in data: # Iterates just through the keys, ignoring the values
for key, value in d.items(): # Iterates through the pairs
for key in d.keys(): # Iterates just through key, ignoring the values
for value in d.values(): # Iterates just through value, ignoring the keys

Utwórz słownik z dwóch list

data = dict(zip(list_with_keys, list_with_values))

Nowy w Python 3.5

Tworzenie scalonego słownika bez modyfikowania oryginałów:

Wykorzystuje to nowy sposób zwany rozpakowywaniem słownika .

data = {**data1, **data2, **data3}

Nowy w Python 3.9

Zaktualizuj lub dodaj wartości dla istniejącego słownika

Operator aktualizacja |= pracuje teraz dla słowników:

data |= {'c':3,'d':4}

Tworzenie scalonego słownika bez modyfikowania oryginałów

Operator scalania | pracuje teraz dla słowników:

data = data1 | {'c':3,'d':4}

Dodaj więcej!

Yugal Jindle
źródło
145

„Czy można dodać klucz do słownika Python po jego utworzeniu? Nie wydaje się, aby miał metodę .add ().”

Tak, jest to możliwe i ma metodę, która to implementuje, ale nie chcesz jej używać bezpośrednio.

Aby zademonstrować, jak i jak go nie używać, stwórzmy pusty dykt z literałem {}:

my_dict = {}

Najlepsza praktyka 1: Notacja indeksu dolnego

Aby zaktualizować ten słownik jednym nowym kluczem i wartością, możesz użyć notacji w indeksie dolnym (patrz Odwzorowania tutaj), która przewiduje przypisanie pozycji:

my_dict['new key'] = 'new value'

my_dict jest teraz:

{'new key': 'new value'}

Najlepsza praktyka 2: updateMetoda - 2 sposoby

Możemy również efektywnie aktualizować słownik o wiele wartości, korzystając z tej updatemetody . Możemy niepotrzebnie tworzyć dicttutaj dodatkowe , więc mamy nadzieję, że nasz dictjuż został stworzony i pochodzi z lub został wykorzystany w innym celu:

my_dict.update({'key 2': 'value 2', 'key 3': 'value 3'})

my_dict jest teraz:

{'key 2': 'value 2', 'key 3': 'value 3', 'new key': 'new value'}

Innym skutecznym sposobem na wykonanie tego przy użyciu metody aktualizacji są argumenty słów kluczowych, ale ponieważ muszą to być poprawne słowa python, nie możesz mieć spacji lub specjalnych symboli ani zaczynać nazwy od liczby, ale wielu uważa to za bardziej czytelny sposób aby utworzyć klucze do nagrania, a tutaj z pewnością unikamy tworzenia dodatkowego niepotrzebnego dict:

my_dict.update(foo='bar', foo2='baz')

i my_dictjest teraz:

{'key 2': 'value 2', 'key 3': 'value 3', 'new key': 'new value', 
 'foo': 'bar', 'foo2': 'baz'}

Więc teraz omówiliśmy trzy Pythoniczne sposoby aktualizacji dict.


Metoda magiczna __setitem__i dlaczego należy jej unikać

Jest inny sposób aktualizacji dict, którego nie powinieneś używać, który wykorzystuje tę __setitem__metodę. Oto przykład, w jaki sposób można użyć tej __setitem__metody, aby dodać parę klucz-wartość do dict, oraz demonstrację słabej wydajności jej użycia:

>>> d = {}
>>> d.__setitem__('foo', 'bar')
>>> d
{'foo': 'bar'}


>>> def f():
...     d = {}
...     for i in xrange(100):
...         d['foo'] = i
... 
>>> def g():
...     d = {}
...     for i in xrange(100):
...         d.__setitem__('foo', i)
... 
>>> import timeit
>>> number = 100
>>> min(timeit.repeat(f, number=number))
0.0020880699157714844
>>> min(timeit.repeat(g, number=number))
0.005071878433227539

Widzimy więc, że używanie notacji w indeksie dolnym jest w rzeczywistości znacznie szybsze niż używanie __setitem__. Robienie rzeczy w języku Python, to znaczy używanie języka w sposób, w jaki był przeznaczony, zwykle jest bardziej czytelne i wydajne obliczeniowo.

Aaron Hall
źródło
1
Różnica jest raczej mniej wyraźna w 2020 r. (Na moim komputerze, indeksowanie 1,35 ms w porównaniu z 2 ms dla d.__setitem__), chociaż wniosek (a zwłaszcza ostatnie zdanie) pozostaje niezmienny. Podniesienie wyszukiwania nazwy metody z pętli skróciło czas do około 1,65 ms; pozostała różnica prawdopodobnie wynika w dużej mierze z nieuniknionego narzutu mechanizmu wywoływania Pythona.
holdenweb
96
dictionary[key] = value
Jason Creighton
źródło
58

Jeśli chcesz dodać słownik do słownika, możesz to zrobić w ten sposób.

Przykład: dodaj nowy wpis do słownika i słownika podrzędnego

dictionary = {}
dictionary["new key"] = "some new entry" # add new dictionary entry
dictionary["dictionary_within_a_dictionary"] = {} # this is required by python
dictionary["dictionary_within_a_dictionary"]["sub_dict"] = {"other" : "dictionary"}
print (dictionary)

Wynik:

{'new key': 'some new entry', 'dictionary_within_a_dictionary': {'sub_dict': {'other': 'dictionarly'}}}

UWAGA: Python wymaga, aby najpierw dodać sub

dictionary["dictionary_within_a_dictionary"] = {}

przed dodaniem wpisów.

Asher
źródło
13
jest to bez znaczenia dla
zadanego
2
Nic nie powstrzyma cię przed zrobieniem tego w jednym wierszu: dictionary = {"dictionary_within_a_dictionary": {"sub_dict": {"other" : "dictionary"}}}(lub jeśli dictionaryjest to już dyktat dictionary["dictionary_within_a_dictionary"] = {"sub_dict": {"other" : "dictionary"}})
Chris
43

Ortodoksyjna składnia jest taka d[key] = value, ale jeśli na klawiaturze brakuje kwadratowych klawiszy nawiasów, możesz:

d.__setitem__(key, value)

W rzeczywistości definiowanie __getitem__i __setitem__metody są sposobem, w jaki możesz sprawić, by twoja klasa obsługiwała składnię nawiasu kwadratowego. Zobacz https://python.developpez.com/cours/DiveIntoPython/php/endiveintopython/object_oriented_framework/special_class_methods.php

Pułkownik Panika
źródło
16
Bardzo trudno byłoby mi programować w Pythonie bez klawiszy nawiasu na klawiaturze.
Bobort
2
To był jedyny sposób, w jaki mogłem znaleźć wartości słownika w ramach listy. Dzięki
Chris Stevens
3
@chrisstevens, jeśli chcesz ustawić wartość w rozumieniu, jakim jest hack, którego użyłem [a for a in my_dict if my_dict.update({'a': 1}) is None].
Jeremy Logan,
Ciekawe ... czy ten (tj. Brakujący nawias kwadratowy) jest powszechny?
Aleister Tanek JavaScript Mraz
@chrisstevens @JeremyLogan Po co używać rozumienia listy, kiedy można używać rozumienia dict? {v: k for k, v in my_dict.items() if <some_conditional_check>}
ingyhere
36

Możesz utworzyć jeden:

class myDict(dict):

    def __init__(self):
        self = dict()

    def add(self, key, value):
        self[key] = value

## example

myd = myDict()
myd.add('apples',6)
myd.add('bananas',3)
print(myd)

Daje:

>>> 
{'apples': 6, 'bananas': 3}
Kiriloff
źródło
31

To popularne pytanie dotyczy funkcjonalnych metod łączenia słowników ai b.

Oto niektóre z bardziej prostych metod (przetestowanych w Pythonie 3) ...

c = dict( a, **b ) ## see also https://stackoverflow.com/q/2255878
c = dict( list(a.items()) + list(b.items()) )
c = dict( i for d in [a,b] for i in d.items() )

Uwaga: Pierwsza powyższa metoda działa tylko wtedy, gdy klucze w bsą ciągami znaków.

Aby dodać lub zmodyfikować pojedynczy element , bsłownik będzie zawierał tylko ten jeden element ...

c = dict( a, **{'d':'dog'} ) ## returns a dictionary based on 'a'

Jest to równoważne z ...

def functional_dict_add( dictionary, key, value ):
   temp = dictionary.copy()
   temp[key] = value
   return temp

c = functional_dict_add( a, 'd', 'dog' )
nobar
źródło
8
Ciekawy komentarz na temat pierwszej metody z BDFL Pythona ( tutaj ).
nobar
c = dict( a, **{'d':'dog'} )byłoby lepiej napisane c = dict(a, d='dog'), o ile klucze są znane i nie są obliczane.
holdenweb
21

Udawajmy, że chcesz żyć w niezmiennym świecie i NIE chcesz modyfikować oryginału, ale chcesz stworzyć nowy, dictktóry jest wynikiem dodania nowego klucza do oryginału.

W Python 3.5+ możesz:

params = {'a': 1, 'b': 2}
new_params = {**params, **{'c': 3}}

Odpowiednikiem języka Python 2 jest:

params = {'a': 1, 'b': 2}
new_params = dict(params, **{'c': 3})

Po jednym z tych:

params jest wciąż równy {'a': 1, 'b': 2}

i

new_params jest równe {'a': 1, 'b': 2, 'c': 3}

Będą chwile, kiedy nie będziesz chciał modyfikować oryginału (potrzebujesz jedynie wyniku dodania do oryginału). Uważam, że jest to odświeżająca alternatywa dla następujących:

params = {'a': 1, 'b': 2}
new_params = params.copy()
new_params['c'] = 3

lub

params = {'a': 1, 'b': 2}
new_params = params.copy()
new_params.update({'c': 3})

Odniesienie: https://stackoverflow.com/a/2255892/514866

Campeterson
źródło
2
W długiej rozmowie z moim pro-funkcjonalnym współpracownikiem programistycznym poruszono dobry punkt. Wadą powyższego podejścia jest to, że jeśli ktoś czytający kod nie zna **języka Python (wielu nie zna ), to nie będzie oczywiste, co się dzieje. Są chwile, kiedy faworyzujesz mniej funkcjonalne podejście dla lepszej czytelności.
obozowicz
5
Nie możemy przewidzieć, jaki podzbiór języka Python znają nasi czytelnicy, więc można założyć, że znają cały język, więc szukają w dokumentach części, których nie znają.
Gabriel
17

Tak wiele odpowiedzi i wciąż wszyscy zapomnieli o dziwnie nazwanych, dziwnie zachowanych, a jednak wciąż przydatnych dict.setdefault()

To

value = my_dict.setdefault(key, default)

po prostu robi to:

try:
    value = my_dict[key]
except KeyError: # key not found
    value = my_dict[key] = default

na przykład

>>> mydict = {'a':1, 'b':2, 'c':3}
>>> mydict.setdefault('d', 4)
4 # returns new value at mydict['d']
>>> print(mydict)
{'a':1, 'b':2, 'c':3, 'd':4} # a new key/value pair was indeed added
# but see what happens when trying it on an existing key...
>>> mydict.setdefault('a', 111)
1 # old value was returned
>>> print(mydict)
{'a':1, 'b':2, 'c':3, 'd':4} # existing key was ignored
Michael Ekoka
źródło
5

Jeśli nie dołączasz do dwóch słowników, ale dodajesz nowe pary klucz-wartość do słownika, to użycie notacji w indeksie dolnym wydaje się najlepszym sposobem.

import timeit

timeit.timeit('dictionary = {"karga": 1, "darga": 2}; dictionary.update({"aaa": 123123, "asd": 233})')
>> 0.49582505226135254

timeit.timeit('dictionary = {"karga": 1, "darga": 2}; dictionary["aaa"] = 123123; dictionary["asd"] = 233;')
>> 0.20782899856567383

Jeśli jednak chcesz dodać na przykład tysiące nowych par klucz-wartość, powinieneś rozważyć użycie tej update()metody.

Burak Özdemir
źródło
3

Myślę, że warto również zwrócić uwagę na collectionsmoduł Pythona, który składa się z wielu przydatnych podklas słowników i opakowań, które upraszczają dodawanie i modyfikowanie typów danych w słowniku , w szczególności defaultdict:

dyktuje podklasę, która wywołuje funkcję fabryczną w celu podania brakujących wartości

Jest to szczególnie przydatne, jeśli pracujesz ze słownikami, które zawsze składają się z tych samych typów danych lub struktur, na przykład ze słownikiem list.

>>> from collections import defaultdict
>>> example = defaultdict(int)
>>> example['key'] += 1
>>> example['key']
defaultdict(<class 'int'>, {'key': 1})

Jeśli klucz jeszcze nie istnieje, defaultdictprzypisuje podaną wartość (w naszym przypadku 10) jako wartość początkową do słownika (często używanego w pętlach). Ta operacja wykonuje zatem dwie czynności: dodaje nowy klucz do słownika (zgodnie z pytaniem) i przypisuje wartość, jeśli klucz jeszcze nie istnieje. W przypadku standardowego słownika spowodowałoby to błąd, ponieważ +=operacja próbuje uzyskać dostęp do wartości, która jeszcze nie istnieje:

>>> example = dict()
>>> example['key'] += 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'key'

Bez użycia defaultdictilość kodu do dodania nowego elementu byłaby znacznie większa i być może wygląda to tak:

# This type of code would often be inside a loop
if 'key' not in example:
    example['key'] = 0  # add key and initial value to dict; could also be a list
example['key'] += 1  # this is implementing a counter

defaultdictmoże być również używany ze złożonymi typami danych, takimi jak listi set:

>>> example = defaultdict(list)
>>> example['key'].append(1)
>>> example
defaultdict(<class 'list'>, {'key': [1]})

Dodanie elementu automatycznie inicjuje listę.

m_____z
źródło
3

Oto inny sposób, którego tu nie widziałem:

>>> foo = dict(a=1,b=2)
>>> foo
{'a': 1, 'b': 2}
>>> goo = dict(c=3,**foo)
>>> goo
{'c': 3, 'a': 1, 'b': 2}

Do odtworzenia słownika można użyć konstruktora słownika i niejawnego rozszerzenia. Co ciekawe, metoda ta może być używana do kontrolowania porządku pozycyjnego podczas budowy słownika ( po Python 3.6 ). W rzeczywistości kolejność wstawiania jest gwarantowana dla Python 3.7 i nowszych!

>>> foo = dict(a=1,b=2,c=3,d=4)
>>> new_dict = {k: v for k, v in list(foo.items())[:2]}
>>> new_dict
{'a': 1, 'b': 2}
>>> new_dict.update(newvalue=99)
>>> new_dict
{'a': 1, 'b': 2, 'newvalue': 99}
>>> new_dict.update({k: v for k, v in list(foo.items())[2:]})
>>> new_dict
{'a': 1, 'b': 2, 'newvalue': 99, 'c': 3, 'd': 4}
>>> 

Powyżej używa zrozumienia słownika.

ingyhere
źródło
2

najpierw sprawdź, czy klucz już istnieje

a={1:2,3:4}
a.get(1)
2
a.get(5)
None

następnie możesz dodać nowy klucz i wartość

Agus Mathew
źródło
0

dodaj klucz słownika, klasa wartości.

class myDict(dict):

    def __init__(self):
        self = dict()

    def add(self, key, value):
        #self[key] = value # add new key and value overwriting any exiting same key
        if self.get(key)!=None:
            print('key', key, 'already used') # report if key already used
        self.setdefault(key, value) # if key exit do nothing


## example

myd = myDict()
name = "fred"

myd.add('apples',6)
print('\n', myd)
myd.add('bananas',3)
print('\n', myd)
myd.add('jack', 7)
print('\n', myd)
myd.add(name, myd)
print('\n', myd)
myd.add('apples', 23)
print('\n', myd)
myd.add(name, 2)
print(myd)
Susan
źródło