2012-03-29 160 views
2

嗨,在我的代码中有一本字典的字典。在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包含在字典中,并且值(字符串)为真或不真实。

+1

如果值不存在,你想返回什么:'False'? – moooeeeep 2012-03-29 07:20:52

回答

3

如果这是一个配置项目,你不需要经常访问它(因此你的效率要求是有问题的)。配置一次并忘记它(例如,设置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 module来验证这个查找确实是软件的瓶颈,这是值得的优化工作。你应该看看timeit module为你的问题选择最高性能的解决方案。

0

只是检查

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

要检查钥匙字典中的使用存在:

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 

此外,如果你想默认值如果密钥不在字典中,请使用get(key, default)方法:

nrec.get('other_config', default_value_here) 
-1

你已经得到了答案

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) 
+0

-1:通过在词典中使用本地方法'.get()',可以做得更好,它的默认值可以配置为第二个参数。 – 2012-03-29 07:21:45

+0

@EtiennePerot - 你说的对,如上所述。 – dfb 2012-03-29 07:38:45

0

一个可能的解决方案是

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

试试这个:

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

如果存在nrec['other_config']'is_guest_installer_network'它会返回它的值

+0

值得一提的是,如果key不存在,那么'get'将返回'None'。无论如何,+1这个。在写我自己的答案(现在已删除)时,我忘了“get”。 – taskinoor 2012-03-29 07:54:28

0

避免异常的最佳方法是使用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') 

如果这就是你需要避免异常的好处,