Oggi ho visto una dichiarazione che non ha fatto eccezione. Qualcuno può spiegare la teoria dietro di esso?Perché un dizionario può essere decompresso come una tupla?
>>> x, y = {'a': 2, 'b': 5}
>>> x
'a'
>>> y
'b'
Oggi ho visto una dichiarazione che non ha fatto eccezione. Qualcuno può spiegare la teoria dietro di esso?Perché un dizionario può essere decompresso come una tupla?
>>> x, y = {'a': 2, 'b': 5}
>>> x
'a'
>>> y
'b'
In Python, ogni iterable possono essere spacchettati :
>>> 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)
>>>
Inoltre, poiché l'iterazione di un dizionario ritorna solo i tasti:
>>> for i in {1:'a', 2:'b', 3:'c'}:
... print i
...
1
2
3
>>>
disimballaggio un dizionario (che itera su di esso) allo stesso modo decomprime solo le sue chiavi.
In realtà, dovrei dire che ogni iterabile possono essere spacchettati finchè i nomi per decomprimere in uguale alla lunghezza del iterabile:
>>> 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
>>>
Ma questa è solo la caso per Python 2.x. In Python 3.x, avete extended iterable unpacking, che permette di decomprimere un iterabile di qualsiasi dimensione (finito) in solo i nomi necessari:
>>> # 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)
>>>
Immagino, questo significa che ogni iterabile può essere decompresso? – aIKid
Sì, ma di solito non ha senso per iterabili che sono mutabili (sia per lunghezza che per contenuto) e ancor meno per iterabili non ordinati. Non avresti modo di aggirare la chiave su cui finire e, in nessun modo di aggirarlo, hai fornito abbastanza variabili da disfare. – aruisdante
@aikid, non gli infiniti –
Iterazione un dict
itera consegna le chiavi. Dal momento che il tuo dict letteral ha esattamente due chiavi, puoi scompattarlo in una tupla da 2.
Questa probabilmente non è una buona pratica in generale, dal momento che i dict non sono ordinati e x == 'b'
e y == 'a'
sarebbe un risultato prefettatamente legale di quel codice.
Grazie per aver detto che non sono ordinati. – Tarik
A partire da Python 3.6, le istruzioni sono ordinate. – gerrit
@gerrit: sì, in cpython, come dettaglio di implementazione. – geoffspear
Nessuna scienza missilistica dietro. dict
è un iterabile, che restituisce le chiavi in ogni iterazione. tuple()
possono ricevere alcuna iterabile come argomento (finché sono finite), quindi:
>>>tuple({'a': 2, 'b': 5})
('a','b')
Vedendo questo, è facile dedurre che disimballaggio funzionerà come mostrato. Inoltre, qualsiasi finita iterabile possono essere spacchettati:
>>> i = iter(range(3))
>>> a,b,c = i
>>> a,b,c
(0, 1, 2)
allo stesso modo possiamo usare '>>> lista ({'a': 2, 'b': 5})' :) –
Nessuna scienza missilistica: D! +1 –
quando eseguire iterazioni su un dizionario, si ottiene le sue chiavi
data = {'a': 2, 'b': 5}
for key in data:
print key
Apertura della confezione non è altro che l'iterazione sopra l'oggetto e mettere gli elementi in le variabili date:
keys = tuple(data) # gives ('a', 'b')
x, y = ('a', 'b')
Quando nel contesto iterabile, dicts sono trattati come (non ordinato) consegna delle chiavi, che è quello che si ottiene w uando si fa list(some_dict)
, che è lo stesso di chiamare keys()
sul dict:
>>> d = {'a': 3, 'b': 5}
>>> list(d)
['a', 'b']
>>> d.keys()
['a', 'b']
Tuttavia, si può anche fare di più.
È possibile decomprimere sia una s dict
' entrambi i tasti e valori se trasformarlo in una lista di coppie prima:
>>> 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
o se si desidera solo le coppie
>>> p1, p2 = d_pairs
>>> print p1, p2
('a', 3) ('b', 5)
o, per dire, solo i tasti:
>>> ((k1, _), (k2, _)) = d_pairs
>>> print k1, k2
a b
ecc.
Ma ovviamente dato che i dizionari - e in generale, non solo in Python - contengono i loro elementi in maniera non ordinata, items()
(in Python) li restituiranno anche in un ordine apparentemente arbitrario, e quindi non c'è c'è modo di sapere quale chiave verrà memorizzato nella quale variabile:
>>> ((k1, v1), (k2, v2)) = {'bar': 3, 'foo': 5}.items()
>>> print k1, v1, k2, v2
foo 5 bar 3
Come si vede, l'ordine delle coppie restituite da items()
è stata invertita in confronto al loro ordine definizione.
+1 per menzionare l'ordinamento non è necessariamente mantenuto intatto quando disimballaggio. –
Dal momento che non è menzionato di seguito, dirò che questa decisione di progettazione è stata probabilmente influenzata dall'utilità. Quando un dict ti dà le sue chiavi, ti dà implicitamente l'accesso ai suoi valori. Se invece restituisse i suoi valori, sarebbe più difficile accedere alle sue chiavi. –