【问题标题】:Python - fast filter large list/dict of objects by attribute valuesPython - 按属性值快速过滤大型对象列表/字典
【发布时间】:2014-11-24 22:50:26
【问题描述】:

我有一个大型订单字典,其中的键等于订单 ID:

class Order():

    def __init__(self, ord_id, price, status='open'):
        self.ord_id = ord_id
        self.price = price
        self.status = status


orders = {'1': <order1>, '2': <order2>, ... , 'N': <orderN>}

如何找到价格小于或等于给定值的订单?过滤每秒发生数千次。在这种情况下,字典/列表理解太慢了。

可能需要自定义索引或一些 b-tree 库或数据库来避免完全循环,但我希望尽可能简单。

满足过滤条件的订单通常占总数的 1%。

【问题讨论】:

    标签: python search filter indexing


    【解决方案1】:

    Python 的生成器通常很快:

    def filterbyprice(seq, max_price):
       for el in seq:
           if seq[el].price <= max_price: yield el
    

    生成器不返回列表,而是一次返回一个元素,因此它们不会消耗内存。

    如果您在循环中调用该函数,这将比创建列表并遍历该列表更快:

    #this is the generator ("yeld" makes the function a generator)
    def filterbyprice(seq, max_price):
       for el in seq:
            if seq[el].price <= max_price: yield el
    
    class Order():
        def __init__(self, ord_id, price, status='open'):
            self.ord_id = ord_id
            self.price = price
            self.status = status
    
    orders = {'1':Order(1,12),'2':Order(1,9),'3':Order(1,1)}
    
    for cheap_order in filterbyprice(orders, 10):
        print cheap_order, orders[cheap_order], orders[cheap_order].price
    

    输出:

    3 <__main__.Order instance at 0x00B90170> 1
    2 <__main__.Order instance at 0x00B90148> 9
    [Finished in 0.2s]
    

    【讨论】:

    • 谢谢,但这并不比 list(dict) comp 快多少,因为在这种情况下,所有订单的完整循环也是必需的。有什么帮助是某种自定义数据结构,其中没有必要遍历所有订单。满足过滤条件的订单通常占总数的 1%。
    • 也许您可以按价格升序对您的orders 字典进行排序,这样您就可以在第一个价格高于给定值时停止过滤循环。 - 有了这个,你必须在插入一些新订单时遍历字典,但你会节省搜索便宜订单的时间。
    • 虽然这是个好主意,但我不能使用它,因为订单实际上比这个问题的例子更复杂,并且有更多的属性可供过滤。
    • 嗯...制作订单ID列表,按价格排序?但这很复杂,不能满足您的“简单就是更好”的要求。
    • “简单”意味着最好不要使用数据库。
    猜你喜欢
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    • 2019-05-04
    • 2016-07-19
    相关资源
    最近更新 更多