需要关于如何用Python表示特定数据结构的建议吗

需要关于如何用Python表示特定数据结构的建议吗,python,Python,我不知道如何用Python表示特定的数据结构。它由组和用户组成,其中每个用户必须恰好是一个组的成员,组应依次包含在容器中,组和用户将仅在此容器中使用。此外,我需要随机访问组和用户。示例数据的JSON表示形式如下所示: { "groupa": { "name": "groupa", "description": "bla", "members": { "usera": { "name":

我不知道如何用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似乎不合适,因为用户和组都有定义良好的属性。由于组和用户仅在容器中使用,因此我提出了一个嵌套类:

class AccountContainer:
    class Group:
        def __init__(self, container, group):
            self.name = group
            self.members = {}
            self.container = container
            self.container.groups[self.name] = self # add myself to container


    class User:
        def __init__(self, group, user, age=None):
            self.name = user
            self.age = age
            self.group = group
            self.group.members[self.name] = self # add myself to group

    def __init__(self):
        self.groups = {}

    def add_user(self, group, username, age=None):
        # possibly check if group exists
        self.groups[group].members[username] = AccountContainer.User(self.groups[group], username, age=age)

    def add_group(self, group):
        self.groups[group] = AccountContainer.Group(self, group)


# creating
c = AccountContainer()
c.add_group("groupa")
c.add_user("groupa", "usera")

# access
c.groups["groupa"].members["usera"].age = 38

# deleting
del(c.groups["groupa"].members["usera"])
  • 您将如何表示这样的数据结构
  • 这是否合理的做法

在我看来,使用一种方法来创建组或用户,而不是引用dicts,似乎有点不自然。

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

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

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

等等

我会觉得使用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}]
  }
]
更新

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

groups_list[random.randrange(len(group_list))] 

<>我认为大量的行为较少类,在多范式语言中(一种类似C++或Python),虽然支持类并不限制你在更简单的结构时使用它们,但它是一种“设计气味”——设计相当于A,尽管是一个温和的。 如果我在做一个代码审查,我会指出这一点,尽管没有什么比让我坚持重新分解更糟糕的了。嵌套类(没有特定的代码行为理由进行嵌套)使这一点更加复杂:它们没有提供特定的好处,另一方面,它们可以“妨碍”,例如在Python中,通过干扰序列化(pickle)

除了好的旧dict和成熟的类之外,Python2.6还提供了一个方便的“structs”替代s,并提供了一组预定义的属性;它们似乎特别适合这个用例


方便的“将此组/用户添加到该容器/组”功能组合在
add…
\uuuu init\uuuuu
方法中,可以重构为独立函数(访问器也可以,尽管问题不那么严重——将内部结构隐藏到独立访问器中可以让您更接近于尊重.

回应亚历克斯的回答。。。。对我来说,这些嵌套类散发着代码气味

也许更简单:

def Group(name=None,description=None,members=None):
    if name is None:  
        name = "UNK!" # some reasonable default
    if members is None:
        members = dict()
    return dict(name = ...., members = ....)
在您最初的方案中,您的对象只是美化了dict,使用对象(在本代码中)的唯一原因是获得一个更干净的init来处理空属性。将它们转换为返回实际dict的函数几乎同样干净,而且容易得多。正如前面指出的,命名元组似乎是一个更好的解决方案


这种(嵌套dicts方法)的优点是从/dump构造到json非常简单。

问题是它不会让我随机访问组。您仍然可以使用随机模块获得随机信息:groups\u list[random.randrange(len(group\u list))]您误解了,随机访问意味着寻址任意元素(此处由其组名标识)理想情况下,在一个固定的时间内,列表是连续的,必须进行搜索,这将是低效的。@Santi-LOL!-现在这是随机访问!我真的不明白你的意思是什么?用户对象是否应该不存储它所包含的组?+1-看起来Python 2.6每天都在变得越来越强大!