我有一个很大的2D(列表列表)列表,每个元素包含一个int列表,字符串和字典。我希望能够在修改过的任何元素上确定'路径'(例如[2] [3] [2] [“项目”] [2]!) 。这个列表是为了大扫描,看看发生了什么变化!理想情况下,我也想要一个新元素的副本,尽管这可以在稍后找到。如何检测嵌套列表的哪些元素已更改? (python)
我的第一次尝试是创建一个类,并覆盖其__setattr__
方法:
class Notify():
def __setattr__(self, name, value):
self.__dict__[name] = value #Actually assign the value
print name, value #This will tell us when it fires
然而,__setattr__
方法设置不是由索引(或键)来访问一个变量时仅火灾,因为这似乎将该调用外包给包含的list()/ dict()类而不是我们的类。
>>> test = Notify()
>>> test.var = 1 #This is detected
var 1
>>> test.var = [1,2,3] #Now let's set it to a list
var [1, 2, 3]
>>> test.var[0] = 12 #But when we assign a value via an index, it doesn't fire
>>> test.var
[12, 2, 3] #However it still assigns the value, so it must be talking to the list itself!
因此,要总结,我想(真的任何方法),告诉我什么(索引/键列表)发生了变化,这需要,因为它发生的情况发生,因为它太昂贵扫描整个列表。我也不能依靠修改列表来提供细节的代码。如果这对于第n个嵌套列表是不可能的,那么我可以使用只给出前两个索引的东西,因为数据不会太大而无法扫描。预先感谢您的帮助!
编辑:仍然没有快乐,虽然这个问题Track changes to lists and dictionaries in python?似乎接近我所需要的。不幸的是,我对班级不太好,需要某个人的帮助!
编辑:看看这个Python: Right way to extend list让我觉得继承list
可能是一个坏主意。我使用代理类代替了以下代码。但是原始问题仍然存在,对嵌套列表的修改不会记录。班级构成,而不是继承是一个好主意?
from UserList import UserList
class NotifyList(UserList):
def __init__(self, initlist=None):
self.data = []
if initlist is not None:
if type(initlist) is list:
self.data[:] = initlist
elif isinstance(initlist, NotifyList):
self.data[:] = initlist.data[:]
else:
self.data = list(initlist)
def __setitem__(self, key, item):
if type(item) is list:
self.data[key] = NotifyList(item)
else:
self.data[key] = item
print key, item
def append(self, item):
if type(item) is list:
self.data.append(NotifyList(item))
else:
self.data.append(item)
print self.index(item), item
也许你可以检查'__setattr__'的值的类型,如果它是一个列表,你可以把它包装在一个通知对象? – lelloman 2014-10-28 12:11:59
此外,您可以添加一些功能以通知类,如父级,所以如果值更改,并且Notify类不是根可以向上传递事件 – lelloman 2014-10-28 12:15:29
也许[this](http://stackoverflow.com/问题/ 8858525/track-changes-to-lists-and-dictionaries-in-python)答案可能对你有所帮助。 – 2014-10-28 12:17:17