Tôi thấy phần Q / A này rất thú vị, vì nó cung cấp một số giải pháp khác nhau cho cùng một vấn đề. Tôi đã lấy tất cả các chức năng này và thử nghiệm chúng với một đối tượng từ điển phức tạp. Tôi đã phải loại bỏ hai chức năng ra khỏi thử nghiệm, vì chúng phải nhận nhiều kết quả không thành công và chúng không hỗ trợ trả về danh sách hoặc phân số dưới dạng giá trị, điều mà tôi thấy cần thiết, vì một hàm nên được chuẩn bị cho hầu hết mọi dữ liệu sắp tới.
Vì vậy, tôi đã bơm các chức năng khác trong 100.000 lần lặp qua timeit
mô-đun và kết quả đầu ra như sau:
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ất cả các hàm đều có cùng một kim để tìm kiếm ('ghi nhật ký') và cùng một đối tượng từ điển, được cấu tạo như thế này:
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ất cả các chức năng đều cho kết quả giống nhau, nhưng sự khác biệt về thời gian là rất lớn! Hàm gen_dict_extract(k,o)
là hàm của tôi được điều chỉnh từ các hàm ở đây, thực ra nó khá giống với find
hàm từ Alfe, với sự khác biệt chính là tôi đang kiểm tra xem đối tượng đã cho có hàm iteritems hay không, trong trường hợp các chuỗi được truyền trong quá trình đệ quy:
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
Vì vậy, biến thể này là nhanh nhất và an toàn nhất trong các chức năng ở đây. Và find_all_items
cực kỳ chậm và xa thứ hai chậm nhất get_recursivley
trong khi phần còn lại, ngoại trừ dict_extract
, là gần nhau. Các chức năng fun
và keyHole
chỉ hoạt động nếu bạn đang tìm kiếm chuỗi.
Khía cạnh học tập thú vị ở đây :)