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

时间:2012-06-22 08:19:09

标签: python

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

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

如果'the-key'已经在cache,则不需要第二行。是否有更好,更短,更具表现力的习语?

8 个答案:

答案 0 :(得分:10)

是的,使用:

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

答案 1 :(得分:8)

可读性很重要!

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

答案 2 :(得分:5)

查看Python装饰器库,更具体地说,Memoize充当缓存。这样你就可以用Memoize装饰器来装饰你的calculate_value

答案 3 :(得分: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

答案 4 :(得分:2)

您还可以使用 defaultdict 执行类似操作:

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

您可以通过提供自己的 factory 函数和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']

答案 5 :(得分:1)

使用setdefault方法,

如果密钥已经不存在,则setdefault创建新密钥,并在第二个参数中提供value,如果密钥已经存在,则返回该密钥的值。 / p>

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

答案 6 :(得分:1)

您可能需要查看(整个页面)“Code like a Pythonista”http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#dictionary-get-method

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

答案 7 :(得分:0)

使用get提取值或获取None
Noneor结合使用,您可以链接另一个操作(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'))