首页 文章

解压缩一般化

提问于
浏览
21
>>> LOL = [[1, 2], ['three']]
>>> [*LOL[0], *LOL[1]]
[1, 2, 'three']

好的!再见itertools.chain . 反正从来没有喜欢过你 .

>>> [*L for L in LOL]
  File "<ipython-input-21-e86d2c09c33f>", line 1
    [*L for L in LOL]
    ^
SyntaxError: iterable unpacking cannot be used in comprehension

Oh . 为什么我们不能拥有美好的东西?

理解中的解包似乎很明显/ pythonic,但由于他们不愿意添加该特殊错误消息,因此有理由禁用它 . 那么,该语法有什么问题?

2 回答

  • 11

    这在PEP 448中简要解释,它引入了解包的概括:

    此PEP的早期迭代允许将列表,集合和字典理解中的运算符解包为容器的可迭代的展平运算符:>>>范围= [范围(5)中的i的范围(i)]

    [*项目范围内的项目]
    [0,0,1,0,1,2,0,1,2,3]

    {*项目范围内的项目}
    {0,1,2,3}
    这引起了人们对可读性和温和支持的强烈担忧 . 为了不使PEP中较少引起争议的方面处于不利地位,该提案的其余部分不接受这一点 .

    但是,这可能会在未来发生变化:

    此PEP不包括列表,集合和字典理解中的解包运算符,尽管未来的提案未被排除 .

  • 16

    引自the Py-Dev mailing list thread in which this feature was accepted

    这样就可以理解了 . IIRC,在补丁的开发过程中,我们意识到f(* x代表x中的x)足够模糊,我们决定不允许它 - 注意f(x代表x中的x)已经有点特殊情况,因为如果参数只是唯一的参数,那么它只能是一个“裸”的生成器表达式 . 相同的推理不适用于(以那种形式)列表,集合和字典理解 - 而f(x表示x中的x)在含义上与f(x表示x中的x)相同,[x表示x在xs]中与[(x表示x中的x)]不同(这是一个元素的列表,元素是生成器表达式)

    (强调我的)

    我还看了一下这个功能的Python问题跟踪器 . 我发现了一个在实施过程中进行讨论的问题 . 帮助他们实现这一目标的消息序列开始于here,其中很好地概述了GvR在msg234766中介绍的歧义 .

    由于害怕链接腐烂,我在这里附加(格式化)消息:

    所以我认为这里的测试函数应该是:def f(* a,** k):print(list(a),list(k))
    然后我们可以尝试这样的事情:f(['ab','cd'中的x为x)
    它打印一个生成器对象,因为它被解释为一个生成器表达式的参数 . 但现在让我们考虑一下:f('x代表['ab','cd']中的x)
    我个人认为这相当于:f(
    'ab','cd')
    IOW:f('a','b','c','d')
    PEP没有说清楚这里要做什么 . 现在的问题是,我们是否应该将
    x替换为x ......作为生成器表达式的扩展形式,或者作为* arg的扩展形式?我不知何故认为后者更有用,也更符合逻辑 . 我的理由是PEP支持诸如f(* a,* b)之类的东西,将f(* x代表x中的x)解释为xs列表中每个x的* x事物是相当合理的 .

    最后,如the Abstract section of the corresponding PEP所述,此功能并未完全排除:

    此PEP不包括列表,集合和字典理解中的解包运算符,尽管未来的提案未被排除 .

    所以,我们可能很快就会看到它(绝对不是3.6,但是:-)而且我希望我们这样做,它们看起来不错 .

相关问题