web-dev-qa-db-fra.com

Python: opérateur Splat / unpack * dans python ne peut pas être utilisé dans une expression?

Est-ce que quelqu'un connaît le raisonnement qui explique pourquoi l'unaire (*) l'opérateur ne peut pas être utilisé dans une expression impliquant des itérateurs/listes/tuples?

Pourquoi est-il limité uniquement au déballage des fonctions? ou ai-je tort de penser cela?

Par exemple:

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

Pourquoi le * opérateur:

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

alors que lorsque le * L'opérateur est utilisé avec un appel de fonction qu'il développe:

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

Il existe une similitude entre les + et le * lors de l'utilisation de listes mais pas lors de l'extension d'une liste avec un autre type.

Par exemple:

# 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
25
Har

Le décompactage dans les littéraux list, dict, set et Tuple a été ajouté dans Python 3.5, comme décrit dans 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]

Ici sont quelques explications de la justification de ce changement. Notez que cela ne fait pas *[1, 2, 3] équivalent à 1, 2, 3 dans tous les contextes. La syntaxe de Python n'est pas destinée à fonctionner de cette façon.

38
B. M.

Astérix * n'est pas simplement un opérateur unaire, c'est un opérateur de décompression d'argument pour définitions de fonctions et appels de fonctions .

Alors * censé être utilisé uniquement pour fonctionner avec les paramètres de fonction et pas avec listes, tuples etc.

REMARQUE: à partir de python3.5, * pourrait être utilisé non seulement avec des fonctions params, @ B. M la réponse décrit largement ce changement en python.

Si vous devez concaténer des listes, utilisez plutôt la concaténation list1 + list2 pour obtenir le résultat souhaité. Pour concaténer la liste et le générateur , passez simplement generator à list objet de type, avant de concaténer avec une autre liste:

gen = (x for x in range(10))
[] + list(gen)
5
Andriy Ivaneyko

Ce n'est pas pris en charge. Python 3 donne un meilleur message (bien que Python 2 ne prend pas en charge * Dans la partie gauche d'une affectation, afaik):

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]) est équivalent à f(4,5,6)

Le déroulement des arguments de fonction est un cas particulier.

3
warvariuc