2016-02-25 26 views
6

Queste domande derivano da PEP 448 -- Additional Unpacking Generalizations ed è presente in Python 3.5 per quanto ne so (e non è backportato a 2.x). Specificamente, nella sezione Svantaggi, si evidenzia quanto segue:Operatore Star * sul lato sinistro e destro di un estratto conto

Mentre *elements, = iterable cause elements per essere un list, elements = *iterable, provoca elements essere un tuple. La ragione di ciò potrebbe confondere le persone che non hanno familiarità con il costrutto.

Il che non davvero tenere, per iterable = [1, 2, 3, 4], il primo caso si ottiene un list:

>>> *elements, = iterable 
>>> elements 
[1, 2, 3, 4] 

Mentre per il secondo caso un tuple viene creato:

>>> elements = *iterable, 
>>> elements 
(1, 2, 3, 4) 

Essere familiarità con il concetto , Sono confuso. Qualcuno può spiegare questo comportamento? L'espressione stellata agisce in modo diverso a seconda del lato su cui si trova?

risposta

6

La differenza tra questi due casi viene spiegata quando si prende in considerazione anche il PEP iniziale per il disimballaggio esteso: PEP 3132 -- Extended iterable unpacking.

in astratto per quella PEP possiamo vedere che:

Questa PEP propone una modifica al iterabile disimballaggio sintassi, che permette di specificare un nome "catch-all", che verrà assegnato un elenco di tutti gli elementi non assegnati a un nome "normale".

(sottolineatura mia)

Quindi nel primo caso, dopo l'esecuzione:

*elements, = iterable 

elements sta andando sempre essere un list contenente tutti gli elementi della iterable.

Anche se sembra simile in entrambi i casi, lo * in questo caso (lato sinistro) significa: catturare tutto ciò che non è assegnato a un nome e assegnarlo all'espressione a stella. Funziona in modo simile a *args e **kwargs do nelle definizioni di funzione .

def spam(*args, **kwargs): 
    """ args and kwargs group positional and keywords respectively """ 

Il secondo caso (destra) è alquanto differente. Qui non abbiamo il * che lavora in un modo "catch all" tanto quanto lo abbiamo funzionante come di solito nelle chiamate alle funzioni . Espande il contenuto del iterabile a cui è collegato.Quindi, la dichiarazione:

elements = *iterable, 

può essere visto come:

elements = 1, 2, 3, 4, 

che è un altro modo per un tuple da inizializzare.

Do nota, un list può essere creato con una semplice usando elements = [*iterable] che spacchettare il contenuto di iterable in [] e risultare in un'assegnazioni della forma elements = [1, 2, 3, 4].