tl; dr
แสดงออกกำเนิดน่าจะเป็นทางออก performant และง่ายที่สุดในการแก้ไขปัญหาของคุณ:
l = [(1,"juca"),(22,"james"),(53,"xuxa"),(44,"delicia")]
result = next((i for i, v in enumerate(l) if v[0] == 53), None)
คำอธิบาย
มีคำตอบหลายประการที่ให้คำตอบง่ายๆสำหรับคำถามนี้พร้อมความเข้าใจในรายการ แม้ว่าคำตอบเหล่านี้จะถูกต้องสมบูรณ์ แต่ก็ไม่เหมาะสม ขึ้นอยู่กับกรณีการใช้งานของคุณอาจมีประโยชน์อย่างมากในการปรับเปลี่ยนง่ายๆบางอย่าง
ปัญหาหลักที่ฉันเห็นกับการใช้ความเข้าใจรายการสำหรับใช้กรณีนี้ก็คือรายชื่อทั้งหมดจะถูกประมวลผลถึงแม้ว่าคุณเพียงต้องการที่จะหา1 องค์ประกอบ
Python มีโครงสร้างง่ายๆซึ่งเหมาะสำหรับที่นี่ มันถูกเรียกว่าการแสดงออกของเครื่องกำเนิดไฟฟ้า นี่คือตัวอย่าง:
l = [(1,"juca"),(22,"james"),(53,"xuxa"),(44,"delicia")]
next((i for i, v in enumerate(l) if v[0] == 53), None)
เราสามารถคาดหวังว่าวิธีนี้จะดำเนินการโดยทั่วไปเหมือนกับการทำความเข้าใจรายการในตัวอย่างเล็กน้อยของเรา แต่ถ้าเราทำงานกับชุดข้อมูลที่ใหญ่ขึ้นล่ะ? นั่นคือข้อได้เปรียบของการใช้วิธีกำเนิดไฟฟ้าเข้ามามีบทบาท แทนที่จะสร้างรายการใหม่เราจะใช้รายการที่มีอยู่ของคุณเป็นรายการที่ทำซ้ำได้และใช้next()
เพื่อรับรายการแรกจากเครื่องกำเนิดไฟฟ้าของเรา
มาดูกันว่าวิธีการเหล่านี้ทำงานแตกต่างกันอย่างไรในชุดข้อมูลขนาดใหญ่บางชุด รายการเหล่านี้เป็นรายการขนาดใหญ่ที่สร้างจาก 10,000,000 + 1 องค์ประกอบโดยมีเป้าหมายของเราที่จุดเริ่มต้น (ดีที่สุด) หรือตอนท้าย (แย่ที่สุด) เราสามารถตรวจสอบได้ว่าทั้งสองรายการนี้จะทำงานอย่างเท่าเทียมกันโดยใช้ความเข้าใจของรายการต่อไปนี้:
แสดงรายการความเข้าใจ
"กรณีที่เลวร้ายที่สุด"
worst_case = ([(False, 'F')] * 10000000) + [(True, 'T')]
print [i for i, v in enumerate(worst_case) if v[0] is True]
"กรณีที่ดีที่สุด"
best_case = [(True, 'T')] + ([(False, 'F')] * 10000000)
print [i for i, v in enumerate(best_case) if v[0] is True]
นิพจน์ตัวสร้าง
นี่คือสมมติฐานของฉันสำหรับเครื่องกำเนิดไฟฟ้า: เราจะเห็นว่าเครื่องกำเนิดไฟฟ้าจะทำงานได้ดีขึ้นอย่างมากในกรณีที่ดีที่สุด แต่ในกรณีที่เลวร้ายที่สุด การเพิ่มประสิทธิภาพนี้ส่วนใหญ่เกิดจากการที่เครื่องกำเนิดไฟฟ้าได้รับการประเมินอย่างเฉื่อยชาซึ่งหมายความว่าจะคำนวณเฉพาะสิ่งที่จำเป็นเพื่อให้ได้ค่าเท่านั้น
กรณีที่เลวร้ายที่สุด
กรณีที่ดีที่สุด
best_case = [(True, 'T')] + ([(False, 'F')] * 10000000)
print next((i for i, v in enumerate(best_case) if v[0] == True), None)
อะไร?! กรณีที่ดีที่สุดทำให้ความเข้าใจในรายการหมดไปแต่ฉันไม่ได้คาดหวังว่ากรณีที่เลวร้ายที่สุดของเราจะทำได้ดีกว่าความเข้าใจในรายการในระดับนี้ นั้นเป็นอย่างไร? ตรงไปตรงมาฉันสามารถคาดเดาได้โดยไม่ต้องค้นคว้าเพิ่มเติม
ใช้ทั้งหมดนี้กับเกลือเม็ดฉันไม่ได้เรียกใช้การทำโปรไฟล์ที่แข็งแกร่งใด ๆ ที่นี่เป็นเพียงการทดสอบขั้นพื้นฐานบางอย่าง สิ่งนี้น่าจะเพียงพอที่จะชื่นชมว่านิพจน์ตัวสร้างมีประสิทธิภาพมากกว่าสำหรับการค้นหารายการประเภทนี้
โปรดทราบว่านี่เป็น python พื้นฐานในตัวทั้งหมด เราไม่จำเป็นต้องนำเข้าอะไรหรือใช้ไลบรารีใด ๆ
ครั้งแรกที่ฉันเห็นเทคนิคนี้ในการค้นหาในหลักสูตรUdacity cs212กับ Peter Norvig