Odpowiedzi:
d = {'key': 'value'}
print(d)
# {'key': 'value'}
d['mynewkey'] = 'mynewvalue'
print(d)
# {'key': 'value', 'mynewkey': 'mynewvalue'}
.update()
metodą? Który jest lepszy kiedy?
d[key]=val
skł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.update
mogę również wziąć inny słownik, ale osobiście wolę nie tworzyć nowego słownika w celu aktualizacji innego.
$foo[ ] = [ . . . . ]
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.
x[-1] = 44
w -1
wartoś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.
Chcę skonsolidować informacje o słownikach Python:
data = {}
# OR
data = dict()
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))}
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)
data.update({'c':3,'d':4}) # Updates 'c' and adds 'd'
data3 = {}
data3.update(data) # Modifies data3, not data
data3.update(data2) # Modifies data3, not data2
del data[key] # Removes specific element in a dictionary
data.pop(key) # Removes the key & returns the value
data.clear() # Clears entire dictionary
key in data
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
data = dict(zip(list_with_keys, list_with_values))
Wykorzystuje to nowy sposób zwany rozpakowywaniem słownika .
data = {**data1, **data2, **data3}
Operator aktualizacja |=
pracuje teraz dla słowników:
data |= {'c':3,'d':4}
Operator scalania |
pracuje teraz dla słowników:
data = data1 | {'c':3,'d':4}
Dodaj więcej!
„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 = {}
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'}
update
Metoda - 2 sposobyMożemy również efektywnie aktualizować słownik o wiele wartości, korzystając z tej update
metody . Możemy niepotrzebnie tworzyć dict
tutaj dodatkowe , więc mamy nadzieję, że nasz dict
już 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_dict
jest 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
.
__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.
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.
dictionary[key] = value
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.
dictionary = {"dictionary_within_a_dictionary": {"sub_dict": {"other" : "dictionary"}}}
(lub jeśli dictionary
jest to już dyktat dictionary["dictionary_within_a_dictionary"] = {"sub_dict": {"other" : "dictionary"}}
)
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
[a for a in my_dict if my_dict.update({'a': 1}) is None]
.
{v: k for k, v in my_dict.items() if <some_conditional_check>}
To popularne pytanie dotyczy funkcjonalnych metod łączenia słowników a
i 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 b
są ciągami znaków.
Aby dodać lub zmodyfikować pojedynczy element , b
sł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' )
c = dict( a, **{'d':'dog'} )
byłoby lepiej napisane c = dict(a, d='dog')
, o ile klucze są znane i nie są obliczane.
Udawajmy, że chcesz żyć w niezmiennym świecie i NIE chcesz modyfikować oryginału, ale chcesz stworzyć nowy, dict
któ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
**
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.
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
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.
Myślę, że warto również zwrócić uwagę na collections
moduł 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, defaultdict
przypisuje 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 defaultdict
ilość 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
defaultdict
może być również używany ze złożonymi typami danych, takimi jak list
i set
:
>>> example = defaultdict(list)
>>> example['key'].append(1)
>>> example
defaultdict(<class 'list'>, {'key': [1]})
Dodanie elementu automatycznie inicjuje listę.
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.
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ść
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)
{**mydict, 'new_key': new_val}
.