2016-01-13 6 views
21

Qualcuno conosce il ragionamento sul motivo per cui l'operatore unario (*) non può essere utilizzato in un'espressione che coinvolge iteratori/elenchi/tuple?Python: l'operatore di Splat/Unpack * in python non può essere utilizzato in un'espressione?

Perché è solo limitato al disimballaggio della funzione? o sbaglio nel pensarlo?

Ad esempio:

>>> [1,2,3, *[4,5,6]] 
File "<stdin>", line 1 
[1,2,3, *[4,5,6]] 
     ^
SyntaxError: invalid syntax 

Perché l'* esercente:

[1, 2, 3, *[4, 5, 6]] give [1, 2, 3, 4, 5, 6] 

mentre quando l'operatore * viene utilizzato con una funzione chiamano fa espandere:

f(*[4, 5, 6]) is equivalent to f(4, 5, 6) 

Esiste una somiglianza tra lo + e * quando si usano gli elenchi ma non quando si estende un elenco con un altro tipo.

Ad esempio:

# This works 
gen = (x for x in range(10)) 

def hello(*args): 
    print args  
hello(*gen) 

# but this does not work 
[] + gen 
TypeError: can only concatenate list (not "generator") to list 
+0

Cosa ti aspetti da quell'utilizzo? Voglio dire, perché vorresti farlo? – Lafexlos

+0

ok aggiornamento della mia domanda – Har

+0

Sembra una domanda a parte: il primo è più correlato alla sintassi, il secondo è solo il comportamento di 'list .__ add__' –

risposta

33

Non permettere l'estrazione in Python 2.x ha osservato e fissato in Python 3.5 che ora ha questa caratteristica, come descritto nella PEP 448:

Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) on Windows (64 bits). 

>>> [1, 2, 3, *[4, 5, 6]] 
[1, 2, 3, 4, 5, 6] 

Here sono alcune spiegazioni per la logica alla base di questo cambiamento.

+0

usa le informazioni complete, ma discutiamo di 'python-2.7' (vedi tag in questione) –

+0

Sembra che siano non aveva considerato l'uso del * all'interno di un contenitore quando si eseguiva python 2.7? – Har

+3

@AndriyIvaneyko risponde alla domanda come richiesto. L'OP vuole conoscere il ragionamento, non come farlo in un altro modo in Py2.7. – timgeb

4

Asterix *non è semplicemente operatore unario, è argomento-disimballaggio operatore per functions definitions e functions calls.

Così * dovrebbero essere utilizzati solo a lavorare con params funzione e non con liste, tuple ecc

NOTA: a partire da python3.5, potrebbero essere utilizzati * non solo con le funzioni params, la risposta di @B. M descrive molto bene il cambiamento in python.

Se è necessario concatenare gli elenchi, utilizzare la concatenazione anziché list1 + list2 per ottenere il risultato desiderato. concatenare lista e generatore semplicemente passare generator a list tipo di oggetto, prima concatenamento con un'altra lista:

gen = (x for x in range(10)) 
[] + list(gen) 
+1

Funziona sia nelle chiamate alle funzioni che nelle definizioni delle funzioni. Sembra un po 'come se tu stia insinuando che funziona solo in quest'ultimo caso, quindi potresti modificare la dicitura. – SuperBiasedMan

+1

@SuperBiasedMan Grazie, per la correzione ho aggiornato la risposta. –

2

Questo non è supportata. Python 3 dà un messaggio migliore (anche se Python 2 non supporta * nella parte sinistra di un'assegnazione, per quanto ne so):

Python 3.4.3+ (default, Oct 14 2015, 16:03:50) 
>>> [1,2,3, *[4,5,6]] 
    File "<stdin>", line 1 
SyntaxError: can use starred expression only as assignment target 
>>> 

f(*[4,5,6]) equivale alla tesi f(4,5,6)

Funzione dispiegarsi è un caso speciale.

+2

Grazie per aver segnalato python 3, l'ho appena provato e funziona in python 3.5.1 >>> [* [1,2,3,4]] => [1, 2, 3, 4] Non ne ero consapevole. Funziona anche con i generatori :) molto bello [1,2,3, (x per x nel range (10))] – Har

Problemi correlati