需要如何用Python表示某个数据结构的建议吗

2024-09-26 17:37:38 发布

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

我不知道如何用Python表示某个数据结构。它由组和用户组成,其中每个用户必须正好是一个组的成员,组应该依次包含在一个容器中,组和用户只能在这个容器中使用。此外,我需要随机访问组和用户。示例数据的JSON表示如下:

{
    "groupa": {
        "name": "groupa",
        "description": "bla",
        "members": {
            "usera": {
                "name": "usera",
                "age": 38
            },
            "userb": {
                "name": "userb",
                "age": 20
            }
        }
    },
    "groupb": {
        "name": "groupb",
        "description": "bla bla",
        "members": {
            "userc": {
                "name": "userc",
                "age": 56
            }
        }
    }
}

简单地使用嵌套dict似乎不合适,因为用户和组都有定义良好的属性。因为组和用户只在容器中使用,所以我设计了一个嵌套类:

^{pr2}$
  • 您如何表示这样的数据结构?在
  • 这是一个合理的方法吗?在

在我看来,在引用dict的同时使用方法创建组或用户有点不自然。在


Tags: 方法用户name数据结构agedescription容器dict
3条回答

我会很舒服地使用dicts。但我会把内容放在列表中,而不是使用dict,这样可以保持内容的整洁,减少冗余:

[
 {
  "name": "groupa",
  "description": "bla",
  "members": [{"name": "usera", "age": 38},
             {"name": "userb","age": 20}]
  },
  {
   "name": "groupb",
   "description": "bla bla",
   "members": [{"name": "userc","age": 56}]
  }
]

更新

您仍然可以通过使用random模块来使用随机元素:

^{pr2}$

我认为大量的行为较少类,在多范式语言中(一种类似C++或Python),虽然支持类并不限制你在更简单的结构时使用它们,而是一种“设计气味”——设计相当于"code smell",虽然是温和的。在

如果我正在对此进行代码复查,我会指出这一点,尽管没有任何地方比让我坚持重新分解更糟糕。嵌套类(没有特定的代码行为原因来嵌套)使这一点更加复杂:它们没有提供任何特定的好处,另一方面也可能“碍事”,例如,在Python中,通过干扰序列化(pickling)。在

除了好的旧字典和成熟的类之外,Python2.6还为带有预定义属性集的“结构”提供了namedtuples的便捷替代方案;它们似乎特别适合于这个用例。在

组合在add...__init__方法中的方便的“将此组/用户添加到该容器/组”功能可以重构为独立函数(访问器也可以,尽管问题不大——将内部结构隐藏到独立访问器中可以使您更接近于尊重Law of Demeter)。在

通常,最好的做法是让对象知道包含它们的内容。将用户传入组,而不是将组传递给用户。仅仅因为您当前的应用程序只使用一次“用户”,每个组一个,每个帐户一个组,并不意味着您应该用这些知识硬编码所有的类。如果您想在其他地方重用User类呢?如果您以后需要支持多个AccountContainer和共同的用户怎么办?在

您还可以从named tuples中获得一些里程,特别是对于您的用户:

User = collections.namedtuple('User', ('name', 'age'))

class Group:
  def __init__(self, name, users=()):
    self.name = name
    self.members = dict((u.name, u) for u in users)

  def add(user):
    self.members[user.name] = user

等等

相关问题 更多 >

    热门问题