我有一个复杂的数据结构(带有元组列表的多维字典),它由多个函数过滤,最后返回一个可删除对象的列表或字典,类似于:
import sys
d1 = {'a': 1, 'd': 3, 'f': 4, 'g': 5, 'h': 6, 'j': 7, 'k': 8, 'l': 9, 's': 2}
d2 = {1: 'a', 2: 's', 3: 'd', 4: 'f', 5: 'g', 6: 'h', 7: 'j', 8: 'k', 9: 'l'}
def filter1(d1, d2):
dd1 = {k:v for k,v in d1.items() if k not in ['a','l']}
dd2 = {k:v for k,v in d2.items() if k not in [4, 6]}
return dict(dd1.items() + dd2.items())
def filter2(d):
return {k:v for k,v in d.items() if not isinstance(v, int) if 3 < k < 8}
f = filter2(filter1(d1,d2))通过查看引用计数,这些对象似乎指向相同的值。此外,它们的ids完全相同。
In [2]: sys.getrefcount(f[5])
Out[2]: 15
In [3]: sys.getrefcount(d2[5])
Out[3]: 15
In [4]:
In [4]: test = d2[5]
In [5]:
In [5]: sys.getrefcount(f[5])
Out[5]: 16
In [6]: sys.getrefcount(d2[5])
Out[6]: 16
In [7]:
In [7]: id(f[5])
Out[7]: 140313621257992
In [8]: id(d2[5])
Out[8]: 140313621257992在过滤了最终产品之后,我基本上得到了一个参考字典。从该字典中删除对象应该会自动从d1、d2中删除原始属性。
我想知道是否可以通过id删除这些对象,或者以某种方式销毁对它们的值的引用,并让垃圾收集器来完成这项工作?
否则,我的过滤器函数必须跟踪每个对象是从哪个dict[key]和哪个list[index]获取的,然后显式删除。这是一项相当困难且容易出错的工作...
所需输出:
for v in f.values():
del v
d2 = {1: 'a', 2: 's', 3: 'd', 4: 'f', 6: 'h', 8: 'k', 9: 'l'}发布于 2015-10-06 23:41:18
不能,您不能使用对象的id()来删除对该对象的引用。您必须从d1和d2中删除正确的键才能删除这些引用。
让过滤器返回一组需要从这些字典中删除的键,然后循环遍历该集并显式删除这些键:
for key in filter2(filter1(d1,d2)):
d1.pop(key, None)
d2.pop(key, None)我使用dict.pop()来允许密钥丢失。
发布于 2015-10-06 23:55:54
我不能用它直接修改你的例子,但是我认为最接近你需求的Python工具是弱引用。
只要对象存在,弱引用就可以引用该对象,但是当对该对象的最后一个硬引用消失时,该对象就不再有效,可以被垃圾回收。当你试图获取一个不再存在的对象的引用时,你只能得到一个None。
因此,如果您希望删除引用字典中的对象将其从原始字典中删除,则必须将原始字典中的对象替换为对引用字典中的对象的弱引用。这样,当你从另一个字典中删除该对象时,弱引用不足以保持该对象的存活,它就会消失。
但正如我在一开始所说的,我不能将其应用到您的示例中,因为您通过保留好的值来构建您的筛选列表,而弱引用将要求您首先将所有内容都放入筛选列表中,然后删除您不想保留的内容。
https://stackoverflow.com/questions/32973172
复制相似问题