【问题标题】:Object vs. Dictionary: how to organise a data tree?对象与字典:如何组织数据树?
【发布时间】:2011-06-18 16:10:23
【问题描述】:

我正在编写某种模拟,其数据以树的形式组织。主要对象是World,它包含一堆方法和City 对象列表。每个City 对象又具有一堆方法和Population 对象列表。 Population 对象没有自己的方法,它们只是持有属性。

我的问题是关于后者Population 对象,我可以从object 派生或创建为字典。组织这些最有效的方法是什么?

这里有几个例子可以说明我的犹豫:

保存数据
我需要能够保存和加载模拟,为此我使用built-in json(我希望数据是人类可读的)。由于程序是按树组织的,因此在每个级别保存数据可能很麻烦。在这种情况下,最好将总体保存为附加到population 列表的字典,作为City 实例的属性。这样,保存只需将City 实例的__dict__ 传递给Json。

使用数据
如果我想操作人口数据,作为类实例比作为字典更容易。不仅语法简单,而且我还可以在编码时更好地享受自省功能。

性能
最后,我不确定在资源方面什么是最有效的。对象和字典到底差别不大,因为每个对象都有一个__dict__属性,可以用来访问它的所有属性。如果我使用大量 CityPopulation 对象运行我的模拟,什么将使用较少的资源:对象或字典?

那么,在树中组织数据的最有效方法是什么?字典或对象更可取吗?或者组织数据树有什么秘诀?

【问题讨论】:

    标签: python object resources dictionary tree


    【解决方案1】:

    为什么不是混合dict/object

    class Population(dict):
        def __getattr__(self, key):
            return self[key]
        def __setattr__(self, key, value):
            self[key] = value
    

    现在您可以通过属性 (foo.bar) 轻松访问已知名称,同时仍然具有 dict 功能来轻松访问未知名称、迭代它们等,而无需笨拙的 getattr/setattr 语法。

    如果您想始终使用特定字段初始化它们,您可以添加一个__init__ 方法:

    def __init__(self, starting=0, birthrate=100, imrate=10, emrate=10, deathrate=100):
         self.update(n=starting, b=birthrate, i=imrate, e=emrate, d=deathrate)
    

    【讨论】:

    • namedtuple 不幸的是,是不可变的。
    • 现在您有了一个类似 javascript 的对象,具有不必要的双向访问功能。 “应该有一种——最好只有一种——明显的方法。”。
    • 谢谢。我真的很喜欢这本,因为它是一本更健康的字典。然而,在保存和加载方面,虽然保存部分很容易,因为它是可读的,但在加载时它仍然很麻烦,因为我必须再次将每个 json 字符串重新加载为混合字典。
    • 在很多地方,Python 有不止一种方法可以做某事。 :-) 我可以看到必须通过您从 JSON 解析的内容并转换所有 dicts 会有些痛苦。
    【解决方案2】:

    正如您自己所见,几乎没有什么实际区别 - 在我看来,主要区别在于,使用单独的硬编码属性对对象(无需引用名称)稍微容易一些,而 dicts 很容易允许将所有值视为一个集合(例如对它们求和)。这就是我选择对象的原因,因为人口对象的数据可能是异构的并且相对独立。

    【讨论】:

      【解决方案3】:

      我认为您应该考虑使用namedtuple(参见collections 模块上的Python docs)。您可以像使用普通类一样按名称访问 Population 对象的属性,例如population.attribute_name 而不是 population['attribute_name'] 用于字典。由于您没有在 Population 类上添加任何方法,这就是您所需要的。

      对于您的“保存数据”标准,还有一个_asdict 方法将字段名称字典返回到您可以传递给json 的值。 (根据您使用的 Python 版本,您可能需要小心从该方法返回的确切内容。有些版本返回字典,有些版本返回 OrderedDict。这可能对您的目的没有任何影响.)

      namedtuples 也非常轻量级,因此它们也适用于您的“运行模拟”资源要求。但是,我会回应其他人的警告,即不要担心这一点,除非您进行一些严肃的数据处理,否则差别将非常小。

      【讨论】:

      • 同样,namedtuple 是不可变的,因此在这里可能不可用。
      【解决方案4】:

      我想说,在任何情况下,人口都是城市的成员,如果只是数据,为什么不使用字典?

      不用担心性能,但如果你真的需要知道,我认为 dict 更快。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-14
        • 2018-07-06
        • 2020-12-06
        • 1970-01-01
        相关资源
        最近更新 更多