สำหรับหลายกรณีการใช้งานคำตอบที่คุณต้องการคือ:
ys = set(y)
[item for item in x if item not in ys]
นี่คือลูกผสมระหว่างคำตอบของ aaronasterlingและคำตอบของ quantumSoupคำตอบของ
เวอร์ชันของ aaronasterling ทำการlen(y)
เปรียบเทียบรายการสำหรับแต่ละองค์ประกอบในx
ดังนั้นจึงใช้เวลากำลังสอง รุ่นของ quantumSoup ใช้ชุดดังนั้นมันจึงทำการค้นหาชุดเวลาคงที่เดียวสำหรับแต่ละองค์ประกอบใน - x
แต่เพราะมันแปลงทั้งสอง x
และy
เป็นเซตมันเสียลำดับขององค์ประกอบของคุณ
ด้วยการแปลงy
เป็นชุดเท่านั้นและวนซ้ำx
ตามลำดับคุณจะได้รับสิ่งที่ดีที่สุดทั้งสองโลก - เวลาเชิงเส้นและการสงวนรักษาลำดับ *
อย่างไรก็ตามสิ่งนี้ยังคงมีปัญหาจากเวอร์ชั่นของ quantumSoup: มันต้องใช้องค์ประกอบของคุณในการแฮช มันสร้างขึ้นในลักษณะของชุด ** ถ้าคุณพยายามที่จะลบรายการ dicts จากรายการ dicts อื่น แต่รายการที่จะลบมีขนาดใหญ่คุณจะทำอย่างไร
หากคุณสามารถตกแต่งค่าของคุณในวิธีที่พวกเขา hashable ที่จะแก้ปัญหา ตัวอย่างเช่นกับพจนานุกรมแฟลตที่มีค่าเป็น hashable:
ys = {tuple(item.items()) for item in y}
[item for item in x if tuple(item.items()) not in ys]
หากประเภทของคุณซับซ้อนขึ้นเล็กน้อย (เช่นบ่อยครั้งที่คุณจัดการกับค่าที่เข้ากันได้กับ JSON ซึ่งแฮชได้หรือแสดงรายการหรือกำหนดค่าที่มีค่าประเภทเดียวกันซ้ำ) คุณยังสามารถใช้โซลูชันนี้ได้ แต่บางประเภทก็ไม่สามารถแปลงเป็นสิ่งที่แฮชได้
หากรายการของคุณไม่ได้และไม่สามารถแฮชได้ แต่สิ่งเหล่านี้สามารถเทียบเคียงได้คุณจะได้รับเวลาบันทึกเชิงเส้นอย่างน้อย ( O(N*log M)
ซึ่งดีกว่าO(N*M)
เวลาแก้ไขรายการมาก แต่ไม่ดีเท่าO(N+M)
เวลาของการแก้ปัญหาชุด) โดยการเรียงลำดับและการใช้bisect
:
ys = sorted(y)
def bisect_contains(seq, item):
index = bisect.bisect(seq, item)
return index < len(seq) and seq[index] == item
[item for item in x if bisect_contains(ys, item)]
หากรายการของคุณไม่แฮชหรือเปรียบเทียบคุณก็ติดอยู่กับวิธีแก้ปัญหากำลังสอง
* โปรดทราบว่าคุณสามารถทำได้โดยใช้OrderedSet
วัตถุคู่หนึ่งซึ่งคุณสามารถค้นหาสูตรอาหารและโมดูลของบุคคลที่สาม แต่ฉันคิดว่ามันง่ายกว่า
** เหตุผลที่การค้นหาการตั้งค่าเป็นเวลาคงที่คือสิ่งที่ต้องทำคือแฮ็กค่าและดูว่ามีรายการสำหรับแฮชนั้นหรือไม่ หากไม่สามารถแฮชค่าได้สิ่งนี้จะไม่ทำงาน