将函数字典转换为结果字典所需的python技巧
我目前对如何有效地做到这一点一无所知。我曾考虑过使用对象,但我不认为它们在这种情况下有什么帮助。有什么想法吗将函数字典转换为结果字典所需的python技巧,python,dictionary,Python,Dictionary,我目前对如何有效地做到这一点一无所知。我曾考虑过使用对象,但我不认为它们在这种情况下有什么帮助。有什么想法吗 from random import choice from copy import deepcopy def main(): def rand_int(): return choice(['yes', 'no']) # any nesting, functions possible spec = { 'answer': r
from random import choice
from copy import deepcopy
def main():
def rand_int():
return choice(['yes', 'no'])
# any nesting, functions possible
spec = {
'answer': rand_int,
'next': {'answer': rand_int},
'the_answer': 42
}
#### looking for elegant (automatic) way to do this
result = deepcopy(spec)
result['answer'] = result['answer']()
result['next']['answer'] = result['next']['answer']()
#### until here
# result2 = ...
print 'result: %s' % result
if __name__ == '__main__':
main()
请不要告诉我使用xsd 您可以在一个 当然,当值不是函数时,这会引发错误,因此如果有可能,我们只需添加一个检查: 然后,我们需要处理这样一个事实,即您的答案需要是递归的,这使得它稍微复杂一些,但不太难修复:
def call_all_callables_in_dict(mapping):
if hasattr(mapping, "items"):
return {key: call_all_callables_in_dict(value) for key, value in mapping.items()}
elif callable(mapping):
return mapping()
else:
return mapping
请注意,如果您的对象具有items
属性或方法,您希望将其存储在dict
中,则此函数将运行,这可能会导致问题。我建议更改该属性或方法的名称,或者将检查替换为isinstance(dict)
我还想指出,对于具有误导性的函数名rand_int
,返回字符串'yes'
或'no'
可能是最糟糕的。通常,在这些情况下,您也需要True
/False
正如在Python2.7之前的注释中所指出的,您可能没有字典理解。为了解决这个问题,dict()
将使用元组生成器,因此您可以像这样替换dict:
{x: y for x, y in something.items()}
与:
因此,全文如下:
from random import choice
def rand_int():
return choice(['yes', 'no'])
spec = {
'answer': rand_int,
'next': {'answer': rand_int},
'the_answer': 42
}
def call_all_callables_in_dict(mapping):
if hasattr(mapping, "items"):
return {key: call_all_callables_in_dict(value) for key, value in mapping.items()}
elif callable(mapping):
return mapping()
else:
return mapping
print(call_all_callables_in_dict(spec))
给了我们:
{'answer': 'no', 'the_answer': 42, 'next': {'answer': 'yes'}}
您可以通过以下方式中的一行执行此操作: 当然,当值不是函数时,这会引发错误,因此如果有可能,我们只需添加一个检查: 然后,我们需要处理这样一个事实,即您的答案需要是递归的,这使得它稍微复杂一些,但不太难修复:
def call_all_callables_in_dict(mapping):
if hasattr(mapping, "items"):
return {key: call_all_callables_in_dict(value) for key, value in mapping.items()}
elif callable(mapping):
return mapping()
else:
return mapping
请注意,如果您的对象具有items
属性或方法,您希望将其存储在dict
中,则此函数将运行,这可能会导致问题。我建议更改该属性或方法的名称,或者将检查替换为isinstance(dict)
我还想指出,对于具有误导性的函数名rand_int
,返回字符串'yes'
或'no'
可能是最糟糕的。通常,在这些情况下,您也需要True
/False
正如在Python2.7之前的注释中所指出的,您可能没有字典理解。为了解决这个问题,dict()
将使用元组生成器,因此您可以像这样替换dict:
{x: y for x, y in something.items()}
与:
因此,全文如下:
from random import choice
def rand_int():
return choice(['yes', 'no'])
spec = {
'answer': rand_int,
'next': {'answer': rand_int},
'the_answer': 42
}
def call_all_callables_in_dict(mapping):
if hasattr(mapping, "items"):
return {key: call_all_callables_in_dict(value) for key, value in mapping.items()}
elif callable(mapping):
return mapping()
else:
return mapping
print(call_all_callables_in_dict(spec))
给了我们:
{'answer': 'no', 'the_answer': 42, 'next': {'answer': 'yes'}}
@TimPietzcker我意识到,当我发布时,更新了这两个方面的答案。语法中还有一个冒号:
{key:value for key,value in dict.items()}
@EmilIvanov实际上,如果您使用的是以前的版本,那么它只是元组生成器表达式的一个微不足道的替换,dict()
,例如:{x:y for…}
会变成dict((x,y)for…
。我不知道我怎么能不把结肠放在那里。谢谢你指出这一点。修正了。这是解决我问题的好办法。非常感谢@TimPietzcker我意识到,当我发布时,更新了这两个方面的答案。语法中还有一个冒号:{key:value for key,value in dict.items()}
@EmilIvanov实际上,如果您使用的是以前的版本,那么它只是元组生成器表达式的一个微不足道的替换,dict()
,例如:{x:y for…}
会变成dict((x,y)for…
。我不知道我怎么能不把结肠放在那里。谢谢你指出这一点。修正了。这是解决我问题的好办法。非常感谢!