12

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

val = cache.get('the-key', calculate_value('the-key'))
cache['the-key'] = val

在 where is 'the-key'already in的情况下,cache不需要第二行。有没有更好、更短、更有表现力的成语?

4

8 回答 8

22

是的,使用:

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}

请参阅:http ://docs.python.org/release/2.5.2/lib/typesmapping.html

于 2012-06-22T08:21:51.613 回答
19

可读性很重要!

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'))

另一种选择是__missing__在缓存类中定义:

class Cache(dict):
    def __missing__(self, key):
        return self.setdefault(key, calculate_value(key))
于 2012-06-22T08:58:09.823 回答
5

看看 Python 装饰器库,更具体地说是作为缓存的Memoize 。这样你就可以calculate_value用 Memoize 装饰器来装饰你的电话。

于 2012-06-22T08:22:02.477 回答
4

接近

cache.setdefault('the-key',calculate_value('the-key'))

如果calculate_value成本不高,那就太好了,因为每次都会对其进行评估。因此,如果您必须从 DB 中读取数据、打开文件或网络连接或做任何“昂贵”的事情,请使用以下结构:

try:
    val = cache['the-key']
except KeyError:
    val = calculate_value('the-key')
    cache['the-key'] = val
于 2012-06-22T08:35:45.620 回答
2

您可能想看看(整个页面)“像 Pythonista 一样的代码” http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#dictionary-get-method

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

于 2012-06-22T08:34:15.060 回答
2

你也可以使用defaultdict来做类似的事情:

>>> from collections import defaultdict
>>> d = defaultdict(int) # will default values to 0
>>> d["a"] = 1
>>> d["a"]
1
>>> d["b"]
0
>>>

你可以通过提供你自己的工厂函数和 itertools.repeat 来分配你想要的任何默认值:

>>> 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']
于 2012-06-22T08:46:11.407 回答
1

使用setdefault方法,

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

val = cache.setdefault('the-key',value)
于 2012-06-22T08:22:30.567 回答
0

使用get提取值或 get None
结合None使用or将让您链接另一个操作(setdefault

def get_or_add(cache, key, value_factory):
    return cache.get(key) or cache.setdefault(key, value_factory())

用法:为了使它变得懒惰,该方法需要一个函数作为第三个参数

get_or_add(cache, 'the-key', lambda: calculate_value('the-key'))
于 2020-04-14T11:57:06.503 回答