繁体   English   中英

在python中访问字典的字典

[英]Accessing dictionary of dictionary in python

嗨,我的代码中有一个字典字典。

nrec={'bridge': 'xapi1', 'current_operations': {}, 'uuid': '9ae5ca7d-e7d6-7a81-f619-d0ea33efb534', 'tags': [], 'other_config': {'is_guest_installer_network': 'true', 'netmask': '255.255.255.0', 'ip_end': '192.168.128.254', 'ip_begin': '192.168.128.1'}, 'name_label': 'Guest installer network', 'VIFs': ['OpaqueRef:dff106aa-1a94-8384-1c86-862b47c87fcf'], 'allowed_operations': [], 'PIFs': [], 'name_description': 'Network on which guests will get assigned a private local IP address', 'MTU': '1500', 'blobs': {}}

在这里您可以在此字典中看到另一个字典'other_config': {'is_guest_installer_network': 'true', 'netmask': '255.255.255.0', 'ip_end': '192.168.128.254', 'ip_begin': '192.168.128.1'}在那儿。

我想检查is_guest_installer_network=="true"

我已经完成了nrec["other_config"]["is_guest_installer_network"]== "true"但问题是某些属性具有带有其他值或空值的other_config属性。 然后在这种情况下,我的解决方案将引发异常。 因此,我想以一种有效的方式执行此操作,例如,如果is_guest_installer_network是包含在字典中且值(字符串)为true或不是。

尝试这个:

nrec["other_config"].get('is_guest_installer_network')

如果nrec['other_config']存在'is_guest_installer_network'它将返回其值

如果这是一个配置项,则您不需要经常访问它(因此您的效率要求将是可疑的)。 self.is_guest_installer_network = True配置一次,然后就self.is_guest_installer_network = True了(例如,设置self.is_guest_installer_network = True )。

如果您不能忘记它,则取决于字典中是否存在该条目。 如果很可能缺少该项目,则执行以下操作可能会更好。 如果某项未命中,您将获得一些快捷方式行为,另一个配置字典仅被查询一次(用于存在性检查和查找后的值)。

def check_guest_installer_network(nrec):
  other_config = nrec.get("other_config", None)
  return other_config is not None and other_config.get('is_guest_installer_network', False)

如果更有可能出现该项目,则惰性尝试/除外方法可能更适合。 当实际需要处理异常时,作为节省的检查性能,将超过额外的性能成本。

def check_guest_installer_network(nrec):
  try:
    return nrec["other_config"]['is_guest_installer_network'] == "true"
  except KeyError:
    return False

毕竟,如果此检查确实对整体性能有重大影响,则应将此变量放置在比嵌套字典更易于访问的位置,例如,一次将其放入全局/类成员变量,并享受价格低廉和之后轻松检查。

您应该查看cprofile模块,以验证此查找确实是软件的瓶颈,值得进行优化。 而且,您应该查看timeit模块 ,以为您的问题选择性能最高的解决方案。

只是检查

'other_config' in nrec and 'is_guest_installer_network' in nrec['other_config'] and nrec['other_config']['is_guest_installer_network'] == 'true'

要检查字典中是否存在键,请使用:

if 'key' in dictionary:
    # do sth

因此,您的代码将是:

if 'other_config' in nrec and 'is_guest_installer_network' in nrec['other_config'] and nrec['other_config']['is_guest_installer_network'] == 'true':
    # do sth

另外,如果您想要默认值(如果该键不存在于dict中),请使用get(key, default)方法:

nrec.get('other_config', default_value_here)

一种可能的解决方案是

>>> try:
    if nrec["other_config1"]["is_guest_installer_network"] == 'true':
        print 'Do Something'
except (KeyError,TypeError):
    None #Or do something logical

避免异常的最佳选择是try .. except或使用dictionary内置方法。

my_dict = {'one': {'two': 'hello world!'}, 'four': 'Dummy!'}
try:
  my_name = my_dict['one']['two']
except:
  pass
  // instead of pass, you can also return something or do something else

try:
  my_dict['one']['two']
except Exception as e:
  my_name = 'default'
  return my_name, e  // returns a tuple which contains 'default' and error message


#or use has_key()

# this is for one-level nested dictionary
for id, items in my_dict.iteritems():
     if items.has_key('two'):
          //do something

# or simply this  --> eliminates dummy for loop
if my_dict['one'].has_key('two'):      // has_key returns True / False
      // do something

# or use in operator  (replace has_key)
if 'two' in my_dict['one'].keys():
     // do something


# or get method

my_dict['one'].get('two', 'Default')

如果这是您避免异常所需的全部内容,Get就是很好的选择。

你有答案

nrec["other_config"]["is_guest_installer_network"]== "true"

可以写成

if nrec.has_key("other_config") and type(nrec["other_config"]) == type({}) and nrec["other_config"].has_key("....") and nrec["other_config"]["is_guest_installer_network"]== "true":

但这有点丑陋。

或者,如评论中所述

nrec.get("other_config",{}).get("is_guest_installer_network",{}) == "true"

但这不能处理类型检查。

也许最好做这样的事情

def traverse(_dict, keys):
    val = _dict
    for key in keys[:-1]:
        if key in val and type(val[key]) is dict :
            val = val[key]
        else:
            return None
    return val.get(keys[-1],None)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM