【问题标题】:Python: Splat/unpack operator * in python cannot be used in an expression?Python:python 中的 Splat/unpack 运算符 * 不能在表达式中使用?
【发布时间】:2016-01-13 12:24:51
【问题描述】:

有人知道为什么不能在涉及迭代器/列表/元组的表达式中使用一元 (*) 运算符的原因吗?

为什么只限于函数解包?还是我想错了?

例如:

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

* 运算符为什么不使用:

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

而当* 运算符与函数调用一起使用时,它会展开:

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

+* 在使用列表时有相似之处,但在使用其他类型扩展列表时则不然。

例如:

# 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

【问题讨论】:

  • 您对这种用法有什么期望?我的意思是,你为什么要这样做?
  • 好的,我更新一下我的问题
  • 这看起来像是两个独立的问题:第一个与语法相关,第二个只是list.__add__的行为

标签: python python-2.7 iterable-unpacking argument-unpacking pep448


【解决方案1】:

在 Python 3.5 中添加了列表、字典、集合和元组文字中的解包功能,如 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 是对这一变化背后的基本原理的一些解释。请注意,这不会使*[1, 2, 3] 在所有情况下都等同于1, 2, 3。 Python 的语法不适合那样工作。

【讨论】:

  • 使用完整信息,但我们讨论的是python-2.7(请参阅相关标签)
  • 似乎他们在制作 python 2.7 时没有考虑在容器中使用 *?
  • @AndriyIvaneyko 这回答了问题。 OP 想知道推理,而不是如何在 Py2.7 中以另一种方式做到这一点。
【解决方案2】:

Asterix * 不仅仅是一元运算符,它是functions definitionsfunctions calls参数解包运算符

所以* 应该用于处理函数参数,而不能用于列表、元组等。

注意:从 python3.5 开始,* 不仅可以与函数参数一起使用,@B. M 的回答很好地描述了 python 的变化。

如果您需要连接列表,请使用连接而不是 list1 + list2 以获得所需的结果。 要连接列表和生成器,只需将generator 传递给list 类型的对象,然后再与另一个列表连接:

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

【讨论】:

  • 它适用于函数调用和函数定义。似乎您在暗示它仅适用于后一种情况,因此您可能需要编辑措辞。
  • @SuperBiasedMan 谢谢,我已经更新了答案。
【解决方案3】:

不支持。 Python 3 提供了更好的信息(尽管 Python 2 不支持在作业的左侧部分中的 *,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]) 等价于f(4,5,6)

函数参数展开是一种特殊情况。

【讨论】:

  • 感谢您指出 python 3,我刚刚尝试过,它在 python 3.5.1 中确实有效 >>> [*[1,2,3,4]] => [1 , 2, 3, 4] 我没有意识到这一点。它甚至可以与生成器一起使用 :) 非常酷 [1,2,3, (x for x in range(10))]
猜你喜欢
  • 2015-06-22
  • 2018-05-14
  • 1970-01-01
  • 1970-01-01
  • 2020-06-22
  • 1970-01-01
  • 2020-07-28
  • 1970-01-01
  • 2014-01-02
相关资源
最近更新 更多