Python:在协同程序中产生Dict元素?

时间:2011-07-16 15:24:57

标签: python dictionary generator coroutine list-comprehension

在我说一句话之前,让我感谢社区作为最近的编程查询的 权威位置。并假装那些称赞不是用文字表达的。无论如何,概率定律指出我偶然发现了使用多功能搜索栏找不到的东西,所以我决定第一次明确要求。也许我只是没有使用Pythonic-enough语言进行搜索。或许我在Googling / Stackoverflowing吮吸。无论...

我正在使用Python协同程序和生成器。从我可以收集到的,你可以做任何生成器理解可以与生产者协同程序,尽管更冗长。我目前正在使用Python 3,虽然任何关于Python 2的答案都不会错过。

所以我假设以下代码片段是等价的:

one_to_three = (num for num in range(1, 4))

...

def one_to_three():
    for num in range(1, 4):
        yield num

one_to_three_gen = one_to_three()

它适用于我的Python安装。如果我忽略该代码中的冗余 - 如此常见的示例,我看到生成器理解很容易映射到生成器协同程序生成的生成器。作为Pragmatic博士,我尝试将相同的概念映射到dicts,因为dict理解已经存在,我认为这两个是等价的:

one_to_three_doubles = {num : num * 2 for num in range(1, 4)}

...

def one_to_three_doubles():
    for num in range(1, 4):
        yield num : num * 2

one_to_three_doubles_gen = one_to_three_doubles()

第一个有效,但第二个没有。它标记第3行冒号的语法错误。

现在,要么我在语法上略微下滑,要么我对生产者协程如何工作有很大的误解。我怀疑它的失败是因为你不能让coroutine返回列表而不是生成器,但我真的不知道。

所以是的,修正这个错误基本上就是我所要求的;提前致谢。我更喜欢一个答案,告诉我答案,而不是给我一个全新的方法来实现结果,但显然如果这是唯一的方法......

2 个答案:

答案 0 :(得分:19)

字典理解确实像列表/集合理解和生成器表达式一样工作 - 具有expr for vars in iterable“体”的X理解几乎等同于X(expr for vars in iterable) - 并且您已经知道如何转动生成器表达成发电机。但请注意“几乎”一点,因为字面翻译不起作用(正如您所注意到的)并且根本不需要(不会使实现变得更容易,而且实际上非常容易)。

Dict理解只是有一点点语法糖看起来更像dict文字(冒号)。在语义上,它没有必要 - 它没有什么特别之处。停下来思考一下:dict理解必须在每次迭代时生成两个值,一个键和一个值。这正是冒号所代表的 - (key, value)对(请记住dict接受(key, value)对的迭代。你不能在dict理解之外使用那个语法糖,但你可以只使用元组。因此,等效的生成器将是:

def one_to_three_doubles():
    for num in range(1, 4):
        yield num, num * 2

答案 1 :(得分:2)

我想从python函数中的yield生成一个dict,并发现了这个问题。下面是返回字典的代码。

def _f():
    yield 'key1', 10
    yield 'key2', 20

def f(): return dict(_f())

print(f())
# Output:
{'key1': 10, 'key2': 20}