pythonic方式索引对象列表

dar*_*ght 6 python indexing dictionary

我有一个对象列表.每个对象都有两个字段

obj1.status = 2
obj1.timestamp = 19211

obj2.status = 3
obj2.timestamp = 14211

obj_list = [obj1, obj2]
Run Code Online (Sandbox Code Playgroud)

我将继续添加/删除列表中的对象以及更改对象的属性,例如我可以将ob1.status更改为5.
现在我有两个dicts

dict1 - <status, object>
dict2 - <timestamp, object> 
Run Code Online (Sandbox Code Playgroud)

如何设计一个简单的解决方案,以便每当我修改/删除/插入列表中的元素时,地图都会自动更新.我对优雅和可扩展的pythonic解决方案感兴趣.例如,在将来,我应该能够轻松地添加另一个属性和dict

同样为了简单起见,我们假设所有属性值都不同.例如,没有两个对象具有相同的状态

Bre*_*bel 2

__setattr__每当您设置值时,您都可以覆盖对象上的 来更新索引。您可以对weakref索引使用字典,这样当您删除对象并且不再使用它们时,它们会自动从索引中删除。

import weakref
from bunch import Bunch


class MyObject(object):

    indexes = Bunch()  # Could just use dict()

    def __init__(self, **kwargs):
        super(MyObject, self).__init__()
        for k, v in kwargs.items():
            setattr(self, k, v)

    def __setattr__(self, name, value):
        try:
            index = MyObject.indexes[name]
        except KeyError:
            index = weakref.WeakValueDictionary()
            MyObject.indexes[name] = index
        try:
            old_val = getattr(self, name)
            del index[old_val]
        except (KeyError, AttributeError):
            pass
        object.__setattr__(self, name, value)
        index[value] = self


obj1 = MyObject(status=1, timestamp=123123)
obj2 = MyObject(status=2, timestamp=2343)


print MyObject.indexes.status[1]
print obj1.indexes.timestamp[2343]
obj1.status = 5
print obj2.indexes['status'][5]
Run Code Online (Sandbox Code Playgroud)

我在这里使用了 a ,Bunch因为它允许您使用.name表示法访问索引,但您可以只使用 adict来代替并使用['name']语法。