我试图提供一个函数作为字典的get函数的默认参数,就像这个
def run():
print "RUNNING"
test = {'store':1}
test.get('store', run())
但是,运行此选项时,它会显示以下输出:
RUNNING
1
所以我的问题是,正如标题所说,有一种方法可以提供一个callable作为get方法的默认值,如果该键存在则不会被调用吗?
答案 0 :(得分:9)
另一个选项,假设您不打算在字典中存储虚假值:
test.get('store') or run()
在python中,or
运算符不会计算不需要的参数(它会短路)
答案 1 :(得分:7)
请参阅dict.get() method returns a pointer的答案和评论中的讨论。你必须把它分成两步。
您的选择是:
如果总是希望将该值作为默认值,并且希望将其存储在defaultdict
中,请使用dict
与callable一起使用。
使用条件表达式:
item = test['store'] if 'store' in test else run()
使用try
/ except
:
try:
item = test['store']
except KeyError:
item = run()
使用get
:
item = test.get('store')
if item is None:
item = run()
这些主题的变化。
glglgl显示了一种子类defaultdict
的方法,在某些情况下你也可以只是dict
的子类:
def run():
print "RUNNING"
return 1
class dict_nokeyerror(dict):
def __missing__(self, key):
return run()
test = dict_nokeyerror()
print test['a']
# RUNNING
# 1
如果总是希望dict
有一些非标准行为,那么子类化才有意义;如果您通常希望它的行为与普通dict
一样,并且只想在一个地方使用惰性get
,请使用我的方法之一2-4。
答案 2 :(得分:2)
我想你只想在密钥不存在时才应用callable。
有几种方法可以做到这一点。
一种方法是使用defaultdict,如果密钥丢失,则调用run()
。
from collections import defaultdict
def run():
print "RUNNING"
test = {'store':1}
test.get('store', run())
test = defaultdict(run, store=1) # provides a value for store
test['store'] # gets 1
test['runthatstuff'] # gets None
另一个相当丑陋的人,只会在dict中保存可以返回适当值的callables。
test = {'store': lambda:1}
test.get('store', run)() # -> 1
test.get('runrun', run)() # -> None, prints "RUNNING".
如果您希望返回值取决于缺少的键,则必须使用defaultdict子类:
class mydefaultdict(defaultdict):
def __missing__(self, key):
val = self[key] = self.default_factory(key)
return val
d = mydefaultdict(lambda k: k*k)
d[10] # yields 100
@mydefaultdict # decorators are fine
def d2(key):
return -key
d2[5] # yields -5
如果你不想将这个值添加到下一个电话的dict中,你有一个
def __missing__(self, key): return self.default_factory(key)
而是每当key: value
对未明确添加{{1}}对时调用默认工厂。
答案 3 :(得分:0)
如果你只知道他可以在调用网站上获得的可调用内容,那么你可以继承dict这样的东西
class MyDict(dict):
def get_callable(self,key,func,*args,**kwargs):
'''Like ordinary get but uses a callable to
generate the default value'''
if key not in self:
val = func(*args,**kwargs)
else:
val = self[key]
return val
然后可以这样使用: -
>>> d = MyDict()
>>> d.get_callable(1,complex,2,3)
(2+3j)
>>> d[1] = 2
>>> d.get_callable(1,complex,2,3)
2
>>> def run(): print "run"
>>> repr(d.get_callable(1,run))
'2'
>>> repr(d.get_callable(2,run))
run
'None'
当可调用计算代价很高时,这可能是最有用的。
答案 4 :(得分:0)
我的项目中有一个A你好B+c de.txt
目录util
,qt.py
,general.py
等。在geom.py
我有一堆python工具,如你需要的那个:
general.py
如果您想支持使用不同的args多次调用默认值,请添加# Use whenever you need a lambda default
def dictGet(dict_, key, default):
if key not in dict_:
return default()
return dict_[key]
:
*args, **kwargs