Menurut saya Tanya Jawab ini sangat menarik, karena memberikan beberapa solusi berbeda untuk masalah yang sama. Saya mengambil semua fungsi ini dan mengujinya dengan objek kamus yang kompleks. Saya harus mengambil dua fungsi dari pengujian, karena mereka memiliki banyak hasil yang gagal dan mereka tidak mendukung daftar yang dikembalikan atau dicts sebagai nilai, yang menurut saya penting, karena suatu fungsi harus disiapkan untuk hampir semua data yang akan datang.
Jadi saya memompa fungsi lain dalam 100.000 iterasi melalui timeitmodul dan keluarannya menghasilkan hasil sebagai berikut:
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)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Semua fungsi memiliki jarum yang sama untuk mencari ('logging') dan objek kamus yang sama, yang dibuat seperti ini:
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]]
}
Semua fungsi memberikan hasil yang sama, tetapi perbedaan waktu sangat dramatis! Fungsinya gen_dict_extract(k,o)adalah fungsi saya yang diadaptasi dari fungsi-fungsi di sini, sebenarnya sangat mirip dengan findfungsi dari Alfe, dengan perbedaan utama, bahwa saya memeriksa apakah objek yang diberikan memiliki fungsi iteritems, jika string dilewatkan selama rekursi:
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
Jadi varian ini adalah fungsi tercepat dan teraman di sini. Dan find_all_itemssangat lambat dan paling lambat kedua get_recursivleysementara sisanya, kecuali dict_extract, dekat satu sama lain. Fungsi fundan keyHolehanya berfungsi jika Anda mencari string.
Aspek pembelajaran yang menarik di sini :)