22

作为一个人为的例子:

myset = set(['a', 'b', 'c', 'd'])
mydict = {item: (yield ''.join([item, 's'])) for item in myset}

list(mydict)给出:

['as', 'cs', 'bs', 'ds', {'a': None, 'b': None, 'c': None, 'd': None}]

这里会发生什么?做什么yield?无论接下来是什么表达,这种行为是否一致yield

注意:我知道做mydict = {item: ''.join([item, 's']) for item in myset}会给字典{'a': 'as', 'b': 'bs', 'c': 'cs', 'd': 'ds'},这似乎是我在这里尝试做的。

4

4 回答 4

12

首先,yield返回什么?这种情况下的答案是None,因为yield返回传递给 的参数next(),在这种情况下什么都不是(list不传递任何东西给next)。

现在这是你的答案:

>>> myset = set(['a', 'b', 'c', 'd'])
>>> mydict = {item: (yield ''.join([item, 's'])) for item in myset}
>>> mydict
<generator object <dictcomp> at 0x0222BB20>

dict 理解变成了生成器,因为您yield在函数体上下文中使用了!这意味着整个事物在传递到list.

所以这就是发生的事情:

  1. list来电next(mydict)
  2. 屈服返回''.join([item, 's'])list冻结理解。
  3. list来电next(mydict)
  4. 理解继续并将yield( None)的结果分配给item字典中并开始新的理解迭代。
  5. 回到 1。

最后,实际的生成器对象返回主体中的临时对象,即dict. 我不知道为什么会发生这种情况,而且可能也没有记录在案的行为。

于 2012-09-10T19:34:20.967 回答
4

我认为这yield会将您出色的字典理解变成生成器表达式。因此,当您在生成器上进行迭代时,yield 正在“生成”看起来as, bs... 但语句yield ...返回的元素None。所以,在一天结束的时候,你会得到一本看起来像{'a': None, 'b': None, ...}.

让我困惑的部分是为什么字典实际上是在最后产生的。我猜这种行为实际上并没有被标准很好地定义,但我可能错了。

有趣的是,如果你用列表理解来尝试这个,python 会抱怨:

>>> a = [(yield i) for i in myset]
  File "<stdin>", line 1
SyntaxError: 'yield' outside function

但是在生成器中没问题(显然)。

于 2012-09-10T19:23:20.553 回答
2

我发现!^_^

在正常生活中,表达

print {item: (yield ''.join([item, 's'])) for item in myset} 

像这样评估:

def d(myset):
    result = {}
    for item in myset:
        result[item] = (''.join([item, 's']))
    yield result

print d(myset).next()

为什么yield result相反return result?我认为有必要像这样支持嵌套列表理解*:

print {i: f.lower() for i in nums for f in fruit}  # yes, it's works

那么,看起来像这样的代码吗?

def d(myset):
    result = {}
    for item in myset:
        result[item] = (yield ''.join([item, 's']))
    yield result

>>> print list(d(myset))
['as', 'cs', 'bs', 'ds', {'a': None, 'b': None, 'c': None, 'd': None}]

首先将返回 dict 的所有值,''.join([item, 's'])最后一个将返回 dict resultyield表达式的值是,None所以 中的值result也是None

* 对评估嵌套列表推导的更正确解释:

print {i: f.lower() for i in nums for f in fruit}

# eval like this:

result = {}
for i, f in product(nums, fruit): # product from itertools
    key, value = (i, f.lower())
    result[key] = value
print result
于 2012-09-10T21:53:20.890 回答
0

我认为您的代码必须执行以下相似性:

def d(myset):
    for item in myset:
        yield item, (yield ''.join([item, 's']))

d(myset)

首先,评估yield ''.join([item, 's'](并返回“as”、“cs”等)。yield 表达式的值为 None,因为被发送回生成器。然后 eval yield item, None,返回元组 ('a', None), ('b', None)。

所以我有:

>>> list(d(myset))
['as', ('a', None), 'cs', ('c', None), 'bs', ('b', None), 'ds', ('d', None)]

接下来会发生什么,我不明白。

于 2012-09-10T21:09:21.287 回答