Bu S / C'yi çok ilginç buldum, çünkü aynı problem için birkaç farklı çözüm sunuyor. Tüm bu işlevleri aldım ve karmaşık bir sözlük nesnesiyle test ettim. Testten iki işlevi çıkarmak zorunda kaldım, çünkü çok sayıda başarısız sonuç vardı ve listelerin veya diktelerin değer olarak döndürülmesini desteklemiyorlardı ki bu benim gerekli bulduğum, çünkü hemen hemen her verinin gelmesi için bir işlevin hazırlanması gerekiyordu .
Bu yüzden diğer fonksiyonları 100.000 yinelemeyle timeit
modül üzerinden pompaladım ve çıktı aşağıdaki sonuca geldi:
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)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Tüm işlevler aramak için aynı iğneye sahipti ('günlüğe kaydetme') ve aynı sözlük nesnesi şu şekilde oluşturuldu:
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]]
}
Tüm işlevler aynı sonucu verdi, ancak zaman farklılıkları çarpıcı! İşlev gen_dict_extract(k,o)
, buradaki işlevlerden uyarlanmış find
işlevimdir , aslında Alfe'nin işlevine çok benzer , temel farkla, özyineleme sırasında dizelerin iletilmesi durumunda verilen nesnenin yineleme işlevi olup olmadığını kontrol ediyorum:
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
Yani bu değişken, buradaki işlevlerin en hızlı ve en güvenli olanıdır. Ve find_all_items
inanılmaz derecede yavaş ve ikinciden çok uzak get_recursivley
, geri kalanlar dict_extract
ise birbirine yakın. İşlevler fun
ve keyHole
yalnızca dizeleri arıyorsanız çalışır.
Burada ilginç öğrenme yönü :)