【发布时间】:2013-05-23 12:16:30
【问题描述】:
给定一个一对一的字典 (=bijection) 生成 à la
for key, value in someGenerator:
myDict[key] = value
可以通过添加轻松创建逆向查找字典
invDict[value] = key
到for 循环。但这是一种 Pythonic 方式吗?我应该写一个class Bijection(dict) 来管理这个倒排字典并提供第二个查找功能吗?或者这样的结构(或类似结构)是否已经存在?
【问题讨论】:
-
这个bidict怎么样
-
从表面上看,
bidict只是用正向和反向映射包装了两个独立的 Python 字典,所以它并不比自己做同样的事情更有效率。事实上,如果您要进行大量键查找,由于函数调用开销,它会慢得多。 -
这几乎不是一个答案,我也没有实际使用它来个人推荐它的经验。不过需要注意的是,如果我没记错的话,关于该库的 API 在使用切片表示法时是否是 Pythonic 存在一些相当激烈的争论。但是,情人眼中的美丽等等。
-
@TobiasKienzler 确实如此。 try/except 块也会减慢速度。在实践中,我发现
return d[k] if k in d else something_else比try: return d[k]\n except KeyError: return something_else和return d.get(k, something_else)快得多,即两个键查找比允许 Python 生成异常和/或调用实例方法更快。就个人而言,我认为它没有提供足够的额外功能(与仅使用两个 dict 相比)来保证其性能问题,但如果这不是问题,那么它至少具有易于使用的优点。 -
@TobiasKienzler 好吧,我最近不得不优化一个相当复杂的递归函数,它被调用了 150,000 次,所以我花了很长时间用
cProfile分析不同的方法,并设法节省了很多使用d[k] if k in d方法的 CPU 时间。后来我将其更改为使用d = collections.defaultdict(lambda: None); v = d[k]; return something_else if v is None else v更好,因为它只需要一个键查找,键未命中只发生一次,并且defaultdict是用 C 实现的。你对namedbidict是正确的 - 我读错了这是第一次。
标签: python dictionary