Python使用多个词典组织数据

时间:2009-11-12 03:42:51

标签: python dictionary grouping

我正在尝试创建一个小型服务器类型的应用程序,并且有关于使用dicts组织数据的问题。现在我正在使用连接套接字对数据进行分组(主要是为了验证它来自何处以及将数据发送回去)。这样的事情:connected[socket] = account_data。基本上,每个关联的人都将拥有帐户数据。由于某些字段将用于比较和检查信息,例如帐户ID,我想用另一个字典来加快速度。

例如:要使用上述方法查找accountID,我必须使用for循环遍历连接中的所有可用连接,查看account_data中的accountID,然后进行比较。这似乎是一种缓慢的方式。如果我可以创建一个字典并使用accountID作为密钥,我认为它可以加快一点。问题是,我计划使用3种不同的序列,所有这些都是不同的。有些数据可能会频繁更改,一旦信息发生变化,更新每个字典似乎更麻烦;无论如何将它们连接在一起?

尝试解释我要问的更简单的方法是: 你有Dict A,Dict B,Dict C和Data。 Dict A,B和C都包含相同的数据。我希望如此,如果数据中的某些内容发生变化,则字典A,B和C中的数据都会发生变化。我当然可以做dict A =数据,dict B =数据等,但在一段时间后会在代码中重复。我知道一旦创建了dict就会设置数据,所以我不确定是否有解决方案。我只是在寻找有关在这种情况下组织数据的最佳方法的建议。

4 个答案:

答案 0 :(得分:2)

首先,不需要复制数据。您可以使用不同的密钥,但每个字典都有3个字典,但其值与其值相同。

这样做你只需要更改一次值对象,这将反映在所有词典中(或者更准确地说,因为词典只存储引用,它们将是最新的)。

接下来,您需要确保“参考完整性”,即如果删除了特定记录,则需要在所有3个词典中删除相应的词典条目,并且如果记录被修改,则具有现在更改的键的词典还需要删除记录并在新密钥下重新添加。这可以通过一个包含所有3个字典并具有Add(),Remove()和(如果适用)Update()方法的类来完成。

答案 1 :(得分:1)

做一些像:

connected[socket] = accountids[account_data.accountid] = account_data

假设account_data是一个带有属性的可变对象,这将引用同一个对象作为两个dicts中的值,当然使用不同的键。 不能在一个语句中,即:

connected[socket] = account_data
accountids[account_data.accountid] = account_data

同一声明中的多个作业只是一种便利;是什么让它以你想要的方式工作是Python通常通过“对象引用”(在赋值,参数传递,返回语句等)中运行。

答案 2 :(得分:0)

也许Python的一个发布/订阅模块可以帮到你吗? 请参阅this question

答案 3 :(得分:0)

如果你有对字典的引用,字典的更新将反映到带引用的所有内容。

客户连接并保留套接字sock。您加载他的帐户并将其粘贴到connections[sock]。然后,您将保留一个帐户ID字典(另一种方式),并引用帐户accounts[account_id]。我们试试吧......

connected = {}
accounts = {}

def load_account(acct):
    return db_magic(acct)                             # Grab a dictionary from the DB

def somebody_connected(sck, acct):
    global connected, accounts
    account = load_account(acct)
    connected[sck] = account                          # Now we have it by socket
    accounts[acct["accountid"]] = account             # Now we have it by account ID

由于我们将account分配到两个不同的地方,因此对该字典(在任一结构中)的任何更改都将反映在另一个中。所以......

def update_username(acct_id, new_username):
    accounts[acct_id]["username"] = new_username

def what_is_my_username(sck):
    sck.send(connected[sck]["username"])              # In response to GIMME_USERNAME

当我们执行update_username时,我们在sck.send中执行的更改会自动获取,因为引用完全相同。