Python:在生成器中生成字典元素?
Posted
技术标签:
【中文标题】Python:在生成器中生成字典元素?【英文标题】:Python: Yield Dict Elements in generators? 【发布时间】:2011-10-06 19:04:20 【问题描述】:在我说一句话之前,让我感谢社区是我最近的编程查询的权威位置。并假装这些赞美不是用语言表达的。无论如何,概率法则决定了我偶然发现了使用多功能搜索栏找不到的东西,所以我决定第一次明确要求。也许我只是没有使用足够 Pythonic 的术语进行搜索。或者我可能不喜欢谷歌搜索/***ing。无论如何...
我在玩 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 行的冒号上标记语法错误。
现在,要么我在语法上稍有失误,要么我对生产者协程的工作方式有很大的误解。我怀疑它失败的原因与您不能让协程返回列表而不是生成器相反,但我真的不知道。
所以,是的,修复该错误基本上就是我所要求的;提前致谢。我更喜欢一个能告诉我答案的答案,而不是给我一个全新的方法来实现结果,但显然如果这是唯一的方法......
【问题讨论】:
您说的是生成器,而不是协程。如果你想知道协程真的是阅读A Curious Course on Coroutines and Concurrency. 我认为同时存在生产者和消费者协程,并且使用 yielding 模式创建序列是协程创建生成器表达式的简单用法,因为执行暂停并在每个值的产生时恢复,它是如何跟踪它的位置的?不过可能是错的。 【参考方案1】:字典推导确实像列表/集合推导和生成器表达式一样工作 - “主体”为 expr for vars in iterable
的 X 推导几乎等同于 X(expr for vars in iterable)
- 而且您已经知道如何将生成器表达式转换为生成器.但请注意“相当多”位,因为直译不起作用(正如您所注意到的)并且根本没有必要(不会使实施变得更容易,实际上会很hacky)。
字典理解只有一点语法糖,看起来更像字典文字(冒号)。从语义上讲,它没有必要——它没有什么特别之处。停下来想一想:dict 理解必须在每次迭代中产生 两个 值,一个键和一个值。这正是冒号所代表的 - (key, value)
对(请记住,dict
接受 (key, value)
对的可迭代)。您不能在 dict 理解之外使用该语法糖,但您可以只对对使用元组。因此,等效的生成器将是:
def one_to_three_doubles():
for num in range(1, 4):
yield num, num * 2
【讨论】:
啊哈,这正是我想知道的;感谢您的及时回复。当你这样陈述它是有道理的,当你提到 dict 接受可迭代的对时,它“点击”了。 要创建字典,请使用dict(one_to_three_doubles())
对@congusbongus 的进一步评论;你也可以写k: v for k, v in one_to_three_doubles()
。当您想要更改结果字典的键或值而不更改生成函数时,这很有用。【参考方案2】:
我想从 python 函数中的 yield 生成一个 dict 并找到了这个问题。下面是返回字典的代码。
def _f():
yield 'key1', 10
yield 'key2', 20
def f(): return dict(_f())
print(f())
# Output:
'key1': 10, 'key2': 20
【讨论】:
以上是关于Python:在生成器中生成字典元素?的主要内容,如果未能解决你的问题,请参考以下文章
Python:在生成器对象上调用 list() 会产生不正确的结果