2016-02-25 10 views
6

Diese Frage stammt aus PEP 448 -- Additional Unpacking Generalizations und ist in Python 3.5 soweit ich weiß (und nicht zurück portiert auf). Insbesondere wird in dem Abschnitt Nachteile wird folgendes angemerkt:Star * -Operator auf der linken oder rechten Seite einer Zuweisungsanweisung

Während *elements, = iterable Ursachen elements ein list zu sein, elements = *iterable verursacht elements ein tuple zu sein. Der Grund dafür kann Leute verwirren, die mit dem Konstrukt nicht vertraut sind.

die in der Tat halten, für iterable = [1, 2, 3, 4] ergibt der erste Fall ein list:

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

Während für den zweiten Fall ein tuple erstellt:

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

mit dem Konzept zu sein, nicht vertraut , Ich bin verwirrt. Kann jemand dieses Verhalten erklären? Handelt der markierte Ausdruck abhängig von der Seite, auf der er sich befindet, unterschiedlich?

Antwort

6

Der Unterschied zwischen diesen beiden Fällen wird erläutert, wenn auch der anfängliche PEP für das erweiterte Entpacken berücksichtigt wird: PEP 3132 -- Extended iterable unpacking.

In der Zusammenfassung für den PEP wir sehen können:

Dieser PEP schlägt eine Änderung Syntax Auspacken Iterable, einen „catch-all“ Namen angeben ermöglichte die eine Liste zugeordnet werden aller Elemente, die keinem "normalen" Namen zugeordnet sind.

(Hervorhebung von mir)

So im ersten Fall, nach der Ausführung:

*elements, = iterable 

elements wird immer sein würde list alle Elemente in der umschließende iterable.

Auch wenn es in beiden Fällen ähnlich aussieht, bedeutet die * in diesem Fall (links): fang alles ab, was keinem Namen zugewiesen ist, und ordne es dem markierten Ausdruck zu. Es funktioniert in ähnlicher Weise wie *args und **kwargs tun in Funktionsdefinitionen.

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

zweiter Fall (die rechte Seite) ist etwas anders. Hier haben wir nicht die * arbeiten in einem "alles fangen" Weg so viel wie wir es funktioniert haben, wie es normalerweise in Funktionsaufrufe funktioniert. Es erweitert den Inhalt des iterierbaren Objekts, an das es angehängt ist.So ist die Aussage:

elements = 1, 2, 3, 4, 

, die eine andere Art und Weise ist für eine tuple initialisiert werden:

elements = *iterable, 

kann eingesehen werden.

Do Note, ein list kann durch einfache erstellt wird elements = [*iterable] mit denen Sie den Inhalt iterable in [] auspacken werden und elements = [1, 2, 3, 4] in einer Zuweisung der Form führen.