去除字典、列表、元组中的循环引用

2024-03-29 06:03:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我有下面这段真正的黑客代码,它从dicttuplelist对象构建的任何类型的数据结构中删除循环引用。在

import ast

def remove_circular_refs(o):
    return ast.literal_eval(str(o).replace("{...}", 'None'))

但我不喜欢这有多下流。在不将数据结构转换为字符串表示的情况下,能否做到这一点?在

下面是要测试的结构示例:

^{pr2}$

Tags: 对象代码import数据结构类型returndefast
1条回答
网友
1楼 · 发布于 2024-03-29 06:03:59

不要使用字符串转换,不。只需通过遍历数据结构来检测引用:

def remove_circular_refs(ob, _seen=None):
    if _seen is None:
        _seen = set()
    if id(ob) in _seen:
        # circular reference, remove it.
        return None
    _seen.add(id(ob))
    res = ob
    if isinstance(ob, dict):
        res = {
            remove_circular_refs(k, _seen): remove_circular_refs(v, _seen)
            for k, v in ob.items()}
    elif isinstance(ob, (list, tuple, set, frozenset)):
        res = type(ob)(remove_circular_refs(v, _seen) for v in ob)
    # remove id again; only *nested* references count
    _seen.remove(id(ob))
    return res

这包括dictlisttuplesetfrozenset对象;它记录所看到的每个对象的id(),当它再次被看到时,它被替换为None。在

演示:

^{pr2}$

最后一个测试doc3,包含共享引用;'string 1'和{}在内存中只存在一次,字典包含对这些对象的多个引用。在

相关问题 更多 >