使用具有词典理解的收益率

时间:2012-09-10 19:18:06

标签: python generator yield

作为一个人为的例子:

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 个答案:

答案 0 :(得分:12)

首先,yield会返回什么?这种情况下的答案是None,因为yield返回传递给next()的参数,在这种情况下没有任何内容(list没有将任何内容传递给{{1} }})。

现在这是你的答案:

next

dict理解变成了生成器,因为你在函数体上下文中使用了>>> myset = set(['a', 'b', 'c', 'd']) >>> mydict = {item: (yield ''.join([item, 's'])) for item in myset} >>> mydict <generator object <dictcomp> at 0x0222BB20> !这意味着在将整个事物传递到yield之前不会对其进行评估。

所以这就是发生的事情:

  1. list来电list
  2. 收益率会将next(mydict)返回''.join([item, 's'])并冻结理解力。
  3. list来电list
  4. 理解恢复并将next(mydict)yield)的结果分配给字典中的None并开始新的理解迭代。
  5. 回到1。
  6. 最后,实际的生成器对象返回正文中的临时对象,即item。为什么会发生这种情况对我来说是未知的,也可能没有记录在案的行为。

答案 1 :(得分:4)

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

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

有趣的是,如果你尝试使用列表解析,python会抱怨:

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

但它Ok in a generator(显然)。

答案 2 :(得分:1)

我找到了! ^ _ ^

在正常生活中,表达

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}]

首先返回''.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

答案 3 :(得分: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',无),('b',无)。

所以,我有:

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

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