Dzisiaj zobaczyłem jedno stwierdzenie, które nie rzuciło wyjątku. Czy ktoś może wyjaśnić tę teorię?Dlaczego można rozpakować słownik jako krotkę?
>>> x, y = {'a': 2, 'b': 5}
>>> x
'a'
>>> y
'b'
Dzisiaj zobaczyłem jedno stwierdzenie, które nie rzuciło wyjątku. Czy ktoś może wyjaśnić tę teorię?Dlaczego można rozpakować słownik jako krotkę?
>>> x, y = {'a': 2, 'b': 5}
>>> x
'a'
>>> y
'b'
W Pythonie co iterable mogą być rozpakowane :
>>> x,y,z = [1, 2, 3] # A list
>>> x,y,z
(1, 2, 3)
>>> x,y,z = 1, 2, 3 # A tuple
>>> x,y,z
(1, 2, 3)
>>> x,y,z = {1:'a', 2:'b', 3:'c'} # A dictionary
>>> x,y,z
(1, 2, 3)
>>> x,y,z = (a for a in (1, 2, 3)) # A generator
>>> x,y,z
(1, 2, 3)
>>>
Ponadto, ponieważ kolejno po słowniku powróci tylko jego klawiszy:
>>> for i in {1:'a', 2:'b', 3:'c'}:
... print i
...
1
2
3
>>>
rozpakowanie słowniku (który iteruje nad nim) podobnie rozpakowuje tylko jego klucze.
Właściwie powinienem powiedzieć, że każdy może iterable być rozpakowane Dopóki nazwiska rozpakować do równa długości iterable:
>>> a,b,c = [1, 2, 3] # Number of names == len(iterable)
>>>
>>> a,b = [1, 2, 3] # Too few names
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)
>>>
>>> a,b,c,d = [1, 2, 3] # Too many names
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: need more than 3 values to unpack
>>>
Ale to dopiero case dla Pythona 2.x. W Pythonie 3.x, masz extended iterable unpacking, który pozwala rozpakować iterowalny dowolnej wielkości (skończonych) w ciągu zaledwie nazwami potrzebujesz:
>>> # Python 3.x interpreter
...
>>> a, *b, c = [1, 2, 3, 4]
>>> a, b, c
(1, [2, 3], 4)
>>>
>>> a, *b = [1, 2, 3, 4]
>>> a, b
(1, [2, 3, 4])
>>>
>>> *a, b, c = [1, 2, 3, 4]
>>> a, b, c
([1, 2], 3, 4)
>>>
Myślę, że to oznacza, że każda iteracja może zostać rozpakowana? – aIKid
Tak, ale zwykle nie ma sensu dla iterables, które są zmienne (zarówno pod względem długości i zawartości), a jeszcze mniej dla iterables nieuporządkowanych. Nie miałbyś możliwości odebrania tego, który klucz został zawarty w miejscu, a żaden sposób dostarczania ci nie dostarczył wystarczającej ilości zmiennych do rozpakowania. – aruisdante
@aikid, nie te nieskończone –
iteracji a dict
iteracje nad klawiszami. Ponieważ twój literał dosłowny ma dokładnie dwa klucze, możesz rozpakować go do 2-krotnej.
Prawdopodobnie nie jest to dobra praktyka, ponieważ dyktanda są nieuporządkowane, a x == 'b'
i y == 'a'
byłyby idealnym wynikiem prawnym tego kodu.
Dzięki za wzmiankę o tym, że są nieuporządkowane. – Tarik
Od Pythona 3.6, dyktury są uporządkowane. – gerrit
@gerrit: tak, w cpython, jako szczegół implementacji. – geoffspear
Brak nauki o rakietach. dict
jest iteracją, która zwraca klucze w każdej iteracji. tuple()
może otrzymać każdy iterable jako argument (o ile są skończone), więc:
>>>tuple({'a': 2, 'b': 5})
('a','b')
Widząc to jest łatwo wywnioskować, że rozpakowanie zadziała jak pokazano. Ponadto każda skończony iterable mogą być rozpakowane:
>>> i = iter(range(3))
>>> a,b,c = i
>>> a,b,c
(0, 1, 2)
podobnie możemy użyć '>>> listy ({'a': 2, 'b': 5})' :) –
Brak nauki o rakietach: D! +1 –
gdy iteracyjne nad słownikiem, masz jej klucze
data = {'a': 2, 'b': 5}
for key in data:
print key
Rozpakowanie to nic innego niż iteracji nad obiektem i umieścić elementy w podane zmienne:
keys = tuple(data) # gives ('a', 'b')
x, y = ('a', 'b')
W kontekście iterowalnym dykta jest traktowana jako (nieuporządkowana) kolekcja kluczy, co stanowi w kura zrobić list(some_dict)
, która jest taka sama jak wywołanie keys()
na dict:
>>> d = {'a': 3, 'b': 5}
>>> list(d)
['a', 'b']
>>> d.keys()
['a', 'b']
Jednak można również zrobić więcej.
można rozpakować zarówno dict
„s oba klawisze i wartości jeśli przekształcić go w liście parach pierwszy:
>>> d = {'a': 3, 'b': 5}
>>> d_pairs = d.items()
>>> print d_pairs
[('a', 3), ('b', 5)]
>>> ((k1, v1), (k2, v2)) = d_pairs
>>> print k1, v1, k2, v2
a 3 b 5
lub jeśli po prostu chcesz pary
>>> p1, p2 = d_pairs
>>> print p1, p2
('a', 3) ('b', 5)
lub, powiedzmy, po prostu klucze:
>>> ((k1, _), (k2, _)) = d_pairs
>>> print k1, k2
a b
itd.
Ale oczywiście, ponieważ słowniki - i ogólnie rozumiem, nie tylko w Pythonie - zawierają swoje pozycje w nie uporządkowany sposób, items()
(w języku Python) również zwrócą je w pozornie arbitralnej kolejności, a zatem istnieje ma sposobu, aby wiedzieć, który klucz będzie przechowywany w tym o zmiennej:
>>> ((k1, v1), (k2, v2)) = {'bar': 3, 'foo': 5}.items()
>>> print k1, v1, k2, v2
foo 5 bar 3
Jak widać, kolejność par zwróconych przez items()
został odwrócony w stosunku do kolejności ich definicji.
+1 za wzmiankę o zamawianiu niekoniecznie jest zachowany w stanie nienaruszonym, gdy rozpakowywanie. –
Ponieważ nie jest to wspomniane poniżej, powiem, że na decyzję o projekcie prawdopodobnie wpłynęła użyteczność. Kiedy dyktuje ci klucze, domyślnie daje ci dostęp do jego wartości. Jeśli zamiast tego zwróci wartości, trudniej będzie uzyskać dostęp do kluczy. –