如何在SortedList中按名称搜索自定义类实例?避免临时对象
优雅解决SortedList按自定义key搜索的问题
不用创建临时Supplier对象,有两种更简洁的方案:
方案一:利用SortedList的keys()方法+bisect模块
SortedList的keys()方法会返回所有元素经过排序key转换后的有序序列,直接用bisect模块搜索目标名称的小写值,再通过索引获取对应元素:
import bisect from sortedcontainers import SortedList class Supplier: def __init__(self, name): self.Name = name # 初始化排序后的列表 suppliers = SortedList(key=lambda x: x.Name.lower()) suppliers.update([Supplier("Apple"), Supplier("Banana"), Supplier("Cherry")]) # 搜索逻辑 target_name = "banana" target_key = target_name.lower() # 获取有序的key列表,用bisect找索引 key_list = list(suppliers.keys()) index = bisect.bisect_left(key_list, target_key) # 验证并获取结果 if index < len(suppliers) and suppliers[index].Name.lower() == target_key: found_supplier = suppliers[index] print(f"找到供应商: {found_supplier.Name}") else: print("未找到匹配的供应商")
方案二:直接复用SortedList的key函数实现二分
借助SortedList内部的_key方法(已经是我们定义的排序逻辑),自己实现极简二分,完全不用临时对象:
from sortedcontainers import SortedList class Supplier: def __init__(self, name): self.Name = name suppliers = SortedList(key=lambda x: x.Name.lower()) suppliers.update([Supplier("Apple"), Supplier("Banana"), Supplier("Cherry")]) def bisect_by_name(sorted_list, name): target_key = name.lower() left, right = 0, len(sorted_list) while left < right: mid = (left + right) // 2 if sorted_list._key(sorted_list[mid]) < target_key: left = mid + 1 else: right = mid return left # 使用示例 index = bisect_by_name(suppliers, "banana") if index < len(suppliers) and suppliers[index].Name.lower() == "banana": print(f"找到供应商: {suppliers[index].Name}")
这两种方案都不用创建临时Supplier实例,比原来的方法更优雅。方案一适合快速实现,方案二更贴近SortedList的内部逻辑,性能也更好(不用额外生成key列表)。
内容的提问来源于stack exchange,提问作者Grant McConville
相关产品推荐
相关产品推荐

