在python dict中获取和设置值的最佳习惯用法

在python dict中获取和设置值的最佳习惯用法,python,Python,我使用dict作为短期缓存。我想从字典中获取一个值,如果字典中还没有该键,请设置它,例如: val = cache.get('the-key', calculate_value('the-key')) cache['the-key'] = val 如果'the-key'已在缓存中,则不需要第二行。有没有更好、更简短、更具表现力的成语呢?是的,请使用: val = cache.setdefault('the-key', calculate_value('the-key')) shell中的一个

我使用
dict
作为短期缓存。我想从字典中获取一个值,如果字典中还没有该键,请设置它,例如:

val = cache.get('the-key', calculate_value('the-key'))
cache['the-key'] = val
如果
'the-key'
已在
缓存中,则不需要第二行。有没有更好、更简短、更具表现力的成语呢?

是的,请使用:

val = cache.setdefault('the-key', calculate_value('the-key'))
shell中的一个示例:

>>> cache = {'a': 1, 'b': 2}
>>> cache.setdefault('a', 0)
1
>>> cache.setdefault('b', 0)
2
>>> cache.setdefault('c', 0)
0
>>> cache
{'a': 1, 'c': 0, 'b': 2}

请参阅:

查看Python装饰器库,更具体地说,它充当缓存。这样,您就可以使用Memoize decorator装饰调用的
计算值。

使用方法

如果键已经不存在,则
setdefault
使用第二个参数中提供的
值创建新键,如果键已经存在,则返回该键的值

val = cache.setdefault('the-key',value)

你可能想看一看“像蟒蛇一样的代码”的整个页面

它涵盖了上面描述的setdefault()技术,defaultdict技术也非常方便地用于制作集合或数组的字典

cache.setdefault('the-key',calculate_value('the-key'))
如果
calculate\u value
成本不高,则该方法非常有效,因为每次都会对其进行评估。因此,如果必须从DB读取数据、打开文件或网络连接或执行任何“昂贵”的操作,请使用以下结构:

try:
    val = cache['the-key']
except KeyError:
    val = calculate_value('the-key')
    cache['the-key'] = val
您还可以使用defaultdict执行类似的操作:

>>> from collections import defaultdict
>>> d = defaultdict(int) # will default values to 0
>>> d["a"] = 1
>>> d["a"]
1
>>> d["b"]
0
>>>
您可以通过提供自己的factory函数和itertools来指定任何默认值。重复:

>>> from itertools import repeat
>>> def constant_factory(value):
...    return repeat(value).next
...
>>> default_value = "default"
>>> d = defaultdict(constant_factory(default_value))
>>> d["a"]
'default'
>>> d["b"] = 5
>>> d["b"]
5
>>> d.keys()
['a', 'b']
可读性很重要

if 'the-key' not in cache:
    cache['the-key'] = calculate_value('the-key')
val = cache['the-key']
如果您真的喜欢一行:

val = cache['the-key'] if 'the-key' in cache else cache.setdefault('the-key', calculate_value('the-key'))
另一个选项是在缓存类中定义
\uuuuuu missing\uuuu

class Cache(dict):
    def __missing__(self, key):
        return self.setdefault(key, calculate_value(key))
用于提取值或获取
None

None
组合将允许您链接另一个操作()

用法: 为了使其惰性,该方法需要一个函数作为第三个参数

get_or_add(cache, 'the-key', lambda: calculate_value('the-key'))

请注意,此代码段计算默认值,而不管它是否在dict中。您当然是对的。在这种特殊情况下,这对我来说无关紧要,因为
calculate\u value
的结果是惰性计算的。这会计算
calculate\u value('the-key')
。@eumiro,对。真倒霉我甚至没有注意到-可能会很昂贵,这取决于
calculate\u value
无论如何。这是最符合Python的答案。defaultdict的问题是它的工厂对一个键一无所知。我知道如果不同的键有不同的默认值,这是必要的,但你只需要对所有键使用一个统一的默认值,defaultdict就足够了。异常也可能会有点昂贵。这取决于调用此代码的频率,以及使用if-then块预期缓存未命中的频率。由于此答案并不总是计算缺少的值,并且提供了更多解决方案,因此它应该是可接受的答案
get_or_add(cache, 'the-key', lambda: calculate_value('the-key'))