<p>我发现这个Q/A非常有趣,因为它为同一个问题提供了几种不同的解决方案。我取了所有这些函数,并用一个复杂的dictionary对象测试它们。我不得不将两个函数从测试中取出,因为它们必须有许多失败的结果,而且它们不支持将列表或dict作为值返回,我认为这是必要的,因为一个函数应该为几乎所有的<em>数据做好准备。</p>
<p>所以我在100.000次迭代中通过<code>timeit</code>模块泵送了其他函数,结果如下:</p>
<pre><code>0.11 usec/pass on gen_dict_extract(k,o)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6.03 usec/pass on find_all_items(k,o)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0.15 usec/pass on findkeys(k,o)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1.79 usec/pass on get_recursively(k,o)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0.14 usec/pass on find(k,o)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0.36 usec/pass on dict_extract(k,o)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
</code></pre>
<p>所有函数都有相同的指针来搜索('logging')和相同的dictionary对象,其结构如下:</p>
<pre><code>o = { 'temparature': '50',
'logging': {
'handlers': {
'console': {
'formatter': 'simple',
'class': 'logging.StreamHandler',
'stream': 'ext://sys.stdout',
'level': 'DEBUG'
}
},
'loggers': {
'simpleExample': {
'handlers': ['console'],
'propagate': 'no',
'level': 'INFO'
},
'root': {
'handlers': ['console'],
'level': 'DEBUG'
}
},
'version': '1',
'formatters': {
'simple': {
'datefmt': "'%Y-%m-%d %H:%M:%S'",
'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
}
}
},
'treatment': {'second': 5, 'last': 4, 'first': 4},
'treatment_plan': [[4, 5, 4], [4, 5, 4], [5, 5, 5]]
}
</code></pre>
<p>所有函数都提供了相同的结果,但时间差异是戏剧性的!函数<code>gen_dict_extract(k,o)</code>是我从这里的函数改编而来的函数,实际上它非常类似于Alfe的<code>find</code>函数,主要区别在于,我检查给定的对象是否有iteritems函数,以防在递归过程中传递字符串:</p>
<pre><code>def gen_dict_extract(key, var):
if hasattr(var,'iteritems'):
for k, v in var.iteritems():
if k == key:
yield v
if isinstance(v, dict):
for result in gen_dict_extract(key, v):
yield result
elif isinstance(v, list):
for d in v:
for result in gen_dict_extract(key, d):
yield result
</code></pre>
<p>所以这个变种是这里最快最安全的函数。而<code>find_all_items</code>的速度非常慢,与第二慢的<code>get_recursivley</code>相差很远,而除<code>dict_extract</code>外,其余的都很近。函数<code>fun</code>和<code>keyHole</code>仅在查找字符串时才起作用。</p>
<p>有趣的学习方面:)</p>