如何根据用户输入比较和替换嵌套字典中的键

时间:2014-01-26 05:15:20

标签: python

H = {'PC1': ['01:01:01:01:01:01', '192.168.0.1', '200', {}],
     'PC2': ['02:02:02:02:02:02',
             '192.168.0.2',
             '200',
             {'192.168.0.1': ('01:01:01:01:01:01', 1390710916.226)}],
     'PC3': ['03:03:03:03:03:03', '192.168.0.3', '200', {}]}

在此词典中,我希望用户输入四个值host_idIPMACtime

首先,用户输入PC1host_id192.168.0.1IP01:01:01:01:01:01MAC,{{1} } 200

注意元组内部是MAC和时间(这不是上面给出的时间,但通过time.time()函数调用)。嵌套字典中的表示键与元组相关联。

现在,如果在下一轮用户输入相同的IP但不同的MAC,例如time192.168.0.1IP04:04:04:04:04:04,我需要检查嵌套字典所有MAC s,以便如果某人有旧PCMAC(对于密钥),则应将其替换为最新信息(新timeMAC) ,但当且仅当(time已经与密钥(time)+ 200相关联)小于当前时间(IP)时。否则,我将从该主机的嵌套字典中删除相关密钥。

因此,在我输入time.time() PC1host_id=PC1IP=192.168.0.1MAC=04:04:04:04:04:04的新信息之后,time=200会更新,因为仅它在嵌套字典中有相关的键。

输出将是:

PC2

注意:可以有多个H = {'PC1': ['01:01:01:01:01:01', '192.168.0.1', '200', {}], 'PC2': ['02:02:02:02:02:02', '192.168.0.2', '200', {'192.168.0.1': ('04:04:04:04:04:04', 1390864671.669904)}], 'PC3': ['03:03:03:03:03:03', '192.168.0.3', '200', {}]} ,用户可以输入任何PC。所以我想检查所有其他host的内部词典。

1 个答案:

答案 0 :(得分:1)

让我们尝试将您的英文描述翻译成Python:

  

我需要检查所有PC的嵌套字典

for key, (mac, ip, time, sub_dict) in H.items():
  

...如果某人有旧的MAC和时间(对于密钥)

我想在这里你要搜索每个sub_dict,将ip映射到(mac, time)对,看看是否有任何一个匹配新条目的mactime

    for sub_ip, (sub_mac, sub_time) in sub_dict.items():
        if (sub_mac, sub_time) == (user_mac, user_time):
  

...当且仅当(时间已经与密钥(IP)+ 200相关联)小于当前时间(time.time())

            if sub_time + 200 < time.time():
  

......应该用最新信息(新的MAC和时间)替换

                sub_dict[sub_ip] = (user_mac, user_time)
  

...否则我将从该主机的嵌套字典中删除相关密钥。

            else:
                del sub_dict[sub_ip]

但是,这会遇到问题。在迭代字典时替换键的值很好,但添加或删除键不是。您可能会收到异常或不正确的结果,或者最糟糕的是,大部分时间都会得到正确的结果,但每隔一段时间就会出现错误的结果。

您可以通过迭代dict副本,或者通过构建新的替换dict来修复此问题,例如,使用理解。

通常,我建议理解,但在这种情况下,你的情况非常复杂,可能难以阅读,所以让我们使用副本。

for key, (mac, ip, time, sub_dict) in H.items():
    for sub_ip, (sub_mac, sub_time) in dict(sub_dict).items():
        if (sub_mac, sub_time) == (user_mac, user_time):
            if sub_time + 200 < time.time():
                sub_dict[sub_ip] = (user_mac, user_time)
            else:
                del sub_dict[sub_ip]

我不确定我是否正确理解了您的描述,但即使我没有,也应该作为您编写所需代码的模板。

正如我在评论中提到的,如果您使用更合理的数据结构,这将更加简单和快速。如果你想要查找,你想要循环的东西应该是字典中的,而不是。如果每个键可以有多个值,那不是问题;只需使用值为集合的字典。如果您需要查找两种方式,可以使用PyPI上的各种“双向字典”实现之一,或使用“索引映射”,单独的字典映射每种“备用密钥”到适当的“主键”。如果我理解你想要做什么以及为什么,我可以给出一个更具体的建议,但希望这足以让你考虑你的数据结构设计。