簡體   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