ฉันพบว่า Q / A นี้น่าสนใจมากเนื่องจากมีวิธีแก้ปัญหาที่แตกต่างกันหลายประการสำหรับปัญหาเดียวกัน ฉันใช้ฟังก์ชันเหล่านี้ทั้งหมดและทดสอบกับวัตถุพจนานุกรมที่ซับซ้อน ฉันต้องนำฟังก์ชันสองฟังก์ชันออกจากการทดสอบเนื่องจากต้องมีผลลัพธ์ที่ล้มเหลวจำนวนมากและพวกเขาไม่สนับสนุนการส่งคืนรายการหรือเขียนตามคำบอกเป็นค่าซึ่งฉันพบว่าจำเป็นเนื่องจากควรเตรียมฟังก์ชันสำหรับข้อมูลเกือบทุกชนิดที่จะมา
ดังนั้นฉันจึงสูบฟังก์ชั่นอื่น ๆ ในการวนซ้ำ 100.000 ผ่านtimeit
โมดูลและผลลัพธ์ออกมาเป็นผลลัพธ์ต่อไปนี้:
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)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ฟังก์ชั่นทั้งหมดมีเข็มเดียวกันในการค้นหา ('การบันทึก') และอ็อบเจ็กต์พจนานุกรมเดียวกันซึ่งสร้างขึ้นในลักษณะนี้:
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]]
}
ฟังก์ชั่นทั้งหมดให้ผลลัพธ์เดียวกัน แต่ความแตกต่างของเวลานั้นน่าทึ่งมาก! ฟังก์ชันgen_dict_extract(k,o)
นี้เป็นฟังก์ชันของฉันที่ดัดแปลงมาจากฟังก์ชันที่นี่จริงๆแล้วมันค่อนข้างเหมือนกับfind
ฟังก์ชันจาก Alfe โดยมีข้อแตกต่างหลักคือฉันกำลังตรวจสอบว่าวัตถุที่กำหนดมีฟังก์ชัน iteritems หรือไม่ในกรณีที่มีการส่งสตริงระหว่างการเรียกซ้ำ:
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
ดังนั้นตัวแปรนี้จึงเป็นฟังก์ชันที่เร็วและปลอดภัยที่สุดที่นี่ และfind_all_items
ช้าอย่างไม่น่าเชื่อและห่างไกลจากวินาทีที่ช้าที่สุดget_recursivley
ในขณะที่ส่วนที่เหลือยกเว้นdict_extract
อยู่ใกล้กัน ฟังก์ชั่นfun
และkeyHole
ใช้งานได้เฉพาะเมื่อคุณกำลังมองหาสตริง
ด้านการเรียนรู้ที่น่าสนใจที่นี่ :)