collections.ChainMap 的目的是什么? [英] What is the purpose of collections.ChainMap?
问题描述
在 Python 3.3 中添加了 ChainMap
类到 collections
模块:
提供了一个 ChainMap 类,用于快速链接多个映射因此它们可以被视为一个单元.它通常比创建一个新字典并运行多个 update() 调用.
示例:
<预><代码>>>>从集合导入 ChainMap>>>x = {'a':1,'b':2}>>>y = {'b': 10, 'c': 11}>>>z = ChainMap(y, x)>>>对于 k, v 在 z.items():打印(k,v)111乙 10据我所知,这是拥有额外字典并使用 维护它的替代方法update()
s.
问题是:
ChainMap
涵盖哪些用例?- 是否有任何
ChainMap
的真实示例? - 是否在切换到python3的第三方库中使用?
额外问题:有没有办法在 Python2.x 上使用它?
<小时>我在 将代码转换为漂亮的惯用 Python
中听说过它Raymond Hettinger 的 PyCon 演讲,我想将它添加到我的工具包中,但我不知道什么时候应该使用它.
我喜欢@b4hand 的例子,事实上我在过去使用过类似 ChainMap 的结构(但不是 ChainMap 本身)用于他提到的两个目的:多-分层配置覆盖和变量堆栈/范围仿真.
我想指出 ChainMap
的另外两个动机/优势/差异,与使用 dict-update 循环相比,因此只存储最终"版本:
更多信息:由于 ChainMap 结构是分层"的,因此它支持回答如下问题:我得到的是默认"值还是被覆盖的值?原始(默认")值是多少?该值在什么级别被覆盖(借用@b4hand 的配置示例:user-config 或 command-line-overrides)?使用简单的字典,回答这些问题所需的信息已经丢失.
速度权衡:假设您有
N
层,每个层最多M
个键,构建 ChainMap 需要O(N)
和每次查找O(N)
最坏情况 [*],而使用更新循环构建 dict 需要O(NM)
和每次查找O(1)
.这意味着如果您经常构建并且每次只执行几次查找,或者如果M
很大,ChainMap 的惰性构建方法对您有利.
[*] (2) 中的分析假设 dict-access 是 O(1)
,而实际上它平均是 O(1)
,并且 <代码>O(M) 最坏的情况.在此处查看更多详情.
In Python 3.3 a ChainMap
class was added to the collections
module:
A ChainMap class is provided for quickly linking a number of mappings so they can be treated as a single unit. It is often much faster than creating a new dictionary and running multiple update() calls.
Example:
>>> from collections import ChainMap
>>> x = {'a': 1, 'b': 2}
>>> y = {'b': 10, 'c': 11}
>>> z = ChainMap(y, x)
>>> for k, v in z.items():
print(k, v)
a 1
c 11
b 10
It was motivated by this issue and made public by this one (no PEP
was created).
As far as I understand, it is an alternative to having an extra dictionary and maintaining it with update()
s.
The questions are:
- What use cases does
ChainMap
cover? - Are there any real world examples of
ChainMap
? - Is it used in third-party libraries that switched to python3?
Bonus question: is there a way to use it on Python2.x?
I've heard about it in Transforming Code into Beautiful, Idiomatic Python
PyCon talk by Raymond Hettinger and I'd like to add it to my toolkit, but I lack in understanding when should I use it.
I like @b4hand's examples, and indeed I have used in the past ChainMap-like structures (but not ChainMap itself) for the two purposes he mentions: multi-layered configuration overrides, and variable stack/scope emulation.
I'd like to point out two other motivations/advantages/differences of ChainMap
, compared to using a dict-update loop, thus only storing the "final" version":
More information: since a ChainMap structure is "layered", it supports answering question like: Am I getting the "default" value, or an overridden one? What is the original ("default") value? At what level did the value get overridden (borrowing @b4hand's config example: user-config or command-line-overrides)? Using a simple dict, the information needed for answering these questions is already lost.
Speed tradeoff: suppose you have
N
layers and at mostM
keys in each, constructing a ChainMap takesO(N)
and each lookupO(N)
worst-case[*], while construction of a dict using an update-loop takesO(NM)
and each lookupO(1)
. This means that if you construct often and only perform a few lookups each time, or ifM
is big, ChainMap's lazy-construction approach works in your favor.
[*] The analysis in (2) assumes dict-access is O(1)
, when in fact it is O(1)
on average, and O(M)
worst case. See more details here.
这篇关于collections.ChainMap 的目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!