解开概括 [英] Unpacking generalizations

查看:173
本文介绍了解开概括的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

>>> LOL = [[1, 2], ['three']]
>>> [*LOL[0], *LOL[1]]
[1, 2, 'three']

好的!再见 itertools.chain .无论如何,从没喜欢过你.

Alright! Goodbye itertools.chain. Never liked you much anyway.

>>> [*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. Why can't we have nice things?

解压缩似乎是很明显的/Python式的,但是由于他们不愿意添加该特殊错误消息,因此有理由将其禁用.那么,该语法有什么问题?

Unpacking in a comprehension seems to be obvious/pythonic, but since they've bothered to add that special error message there was a reason for disabling it. So, what's the problem with that syntax?

推荐答案

引用接受此功能的Py-Dev邮件列表线程:

这样就可以产生理解力了. IIRC,在开发补丁程序时,我们意识到f(*x for x in xs) 足够模糊的 ,因此我们决定禁止使用它-请注意,f(x for x in xs)已经有些特殊了之所以如此,是因为一个参数只能是一个裸"生成器表达式(如果它是唯一的参数).相同的推理不适用于(以这种形式)列出,设置和表达理解-虽然f(x for x in xs)的含义与f((x for x in xs))相同,但[x for x in xs][(x for x in xs)]不同(这是一个列表)一个元素,而该元素是一个生成器 表达式)

So that leaves comprehensions. IIRC, during the development of the patch we realized that f(*x for x in xs) is sufficiently ambiguous that we decided to disallow it -- note that f(x for x in xs) is already somewhat of a special case because an argument can only be a "bare" generator expression if it is the only argument. The same reasoning doesn't apply (in that form) to list, set and dict comprehensions -- while f(x for x in xs) is identical in meaning to f((x for x in xs)), [x for x in xs] is NOT the same as [(x for x in xs)] (that's a list of one element, and the element is a generator expression)

(强调我的)

我还窥视了该功能的Python问题跟踪器.我发现一个问题,在实施过程中进行了讨论. 此处的一系列信息帮助他们实现了这一目标,并很好地介绍了歧义在 msg234766 中由GvR提出.

I also took a peek at the Python issue tracker for this feature. I found an issue in which discussion took place while implementing it. The sequence of messages that helped them come to this realization starts here with a nice overview of the ambiguity introduced presented in msg234766 by GvR.

在link-rot的 fear 中,我在此处附加(格式化的)消息:

In fear of link-rot, I'm attaching the (formatted) message here:

所以我认为这里的测试功能应该是:

So I think the test function here should be:

def f(*a, **k): print(list(a), list(k))

然后我们可以尝试以下操作:

Then we can try things like:

f(x for x in ['ab', 'cd'])

打印一个生成器对象,因为它被解释为一个生成器表达式的参数.

which prints a generator object, because this is interpreted as an argument that's a generator expression.

但是现在让我们考虑:

f(*x for x in ['ab', 'cd'])

我个人希望这等同于:

f(*'ab', *'cd')

IOW:

 f('a', 'b', 'c', 'd')

PEP在此没有明确说明要做什么.现在的问题是,我们应该将诸如*x for x in ...之类的内容解释为生成器表达式的扩展形式,还是作为*arg的扩展形式?我不知何故认为后者更有用,而且逻辑扩展也更合理.

The PEP doesn't give clarity on what to do here. The question now is, should we interpret things like *x for x in ... as an extended form of generator expression, or as an extended form of *arg? I somehow think the latter is more useful and also the more logical extension.

我的理由是PEP支持f(*a, *b)之类的东西,并且将f(*x for x in xs)解释为对列表xs中的每个x*x事情是很合逻辑的.

My reasoning is that the PEP supports things like f(*a, *b) and it would be fairly logical to interpret f(*x for x in xs) as doing the *x thing for each x in the list xs.

最后,如相应PEP的摘要部分,但并未完全排除此功能:

Finally, as noted in the Abstract section of the corresponding PEP, this feature isn't completely ruled out:

此PEP并未在列表,集合和字典理解中包括解包运算符,尽管尚未将其排除在以后的建议之内.

因此,我们可能很快就会看到它(虽然不是:-,绝对不是3.6,),但我希望我们这样做,它们看起来不错.

So, we might get to see it sometime soon (definitely not 3.6, though :-) and I hope we do, they look nice.

这篇关于解开概括的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆