有没有简单的方法来查看复杂字典中是否存在值?

时间:2018-10-31 01:23:06

标签: python dictionary

下面是我正在浏览的一本复杂词典的示例。我想检查“ AccountRoot”是否出现在字典中。请注意,我正在遍历这些词典中的许多内容,并且更改了格式。因此,我想知道是否有类似.find()的函数。我找不到任何内容,看来.find()无效。

示例字典;

{'hash': '752F3B5CEE85F3C2DC60041DCAC4777BECE9CC11585225383F8178EBC2ACFB16',
 'ledger_index': 108843,
 'date': '2013-01-18T22:27:20+00:00',
 'tx': {'TransactionType': 'OfferCreate',
  'Flags': 0,
  'Sequence': 3,
  'TakerPays': '499950000',
  'TakerGets': {'value': '0.05',
   'currency': 'BTC',
   'issuer': 'r4aZ4aqXHfrcYfuFrTqDmSopfgPHnRS9MZ'},
  'Fee': '10',
  'SigningPubKey': '027008A4A7AED7B5426EAC46691CFCAC8CA3CF2773D1CAC4074F0BC58EC24BE883',
  'TxnSignature': '3046022100C38236B533936B4A328346D5246570976B8A1390655EC1B6F4090C42AE73FD8D022100D49E5498C40D90AF7BD02F2818EE04F1D0F6B0C76F0325997190D56BF4B9D82D',
  'Account': 'r4aZ4aqXHfrcYfuFrTqDmSopfgPHnRS9MZ'},
 'meta': {'TransactionIndex': 0,
  'AffectedNodes': [{'CreatedNode': {'LedgerEntryType': 'DirectoryNode',
     'LedgerIndex': '0A624575D3C02D544B92F23F6A8BDF3B10745427B731613820A1695AFF11993B',
     'NewFields': {'ExchangeRate': '5E2386099B1BF000',
      'RootIndex': '0A624575D3C02D544B92F23F6A8BDF3B10745427B731613820A1695AFF11993B',
      'TakerGetsCurrency': '0000000000000000000000004254430000000000',
      'TakerGetsIssuer': 'E767BCB9E1A31C46C16F42DA9DDE55792767F565'}}},
   {'CreatedNode': {'LedgerEntryType': 'DirectoryNode',
     'LedgerIndex': '165845E192D2217A6518C313F3F4B2FD676EE1619FF50CB85E2386099B1BF000',
     'NewFields': {'ExchangeRate': '5E2386099B1BF000',
      'RootIndex': '165845E192D2217A6518C313F3F4B2FD676EE1619FF50CB85E2386099B1BF000',
      'TakerGetsCurrency': '0000000000000000000000004254430000000000',
      'TakerGetsIssuer': 'E767BCB9E1A31C46C16F42DA9DDE55792767F565'}}},
   {'ModifiedNode': {'LedgerEntryType': 'AccountRoot',
     'PreviousTxnLgrSeq': 108839,
     'PreviousTxnID': '8B2921C5222A6814BCF7602A18FEACE94797A644AF893A43FB642C172CC14ED0',
     'LedgerIndex': '481DA662E465CC7888FD3750A0952F2003D78DCAA8CB2E91088E862BB7D30B98',
     'PreviousFields': {'Sequence': 3,
      'OwnerCount': 0,
      'Balance': '9999999980'},
     'FinalFields': {'Flags': 0,
      'Sequence': 4,
      'OwnerCount': 1,
      'Balance': '9999999970',
      'Account': 'r4aZ4aqXHfrcYfuFrTqDmSopfgPHnRS9MZ'}}},
   {'CreatedNode': {'LedgerEntryType': 'Offer',
     'LedgerIndex': '9AABB5DCD201AE7FB0F9B7F90083F48B7451977B2419339ADFEBD8876B54EB66',
     'NewFields': {'Sequence': 3,
      'BookDirectory': '165845E192D2217A6518C313F3F4B2FD676EE1619FF50CB85E2386099B1BF000',
      'TakerPays': '499950000',
      'TakerGets': {'value': '0.05',
       'currency': 'BTC',
       'issuer': 'r4aZ4aqXHfrcYfuFrTqDmSopfgPHnRS9MZ'},
      'Account': 'r4aZ4aqXHfrcYfuFrTqDmSopfgPHnRS9MZ'}}}],
  'TransactionResult': 'tesSUCCESS'}}

2 个答案:

答案 0 :(得分:2)

在这里回答: Finding a key recursively in a dictionary

发布此信息,以便人们使用不同的术语进行搜索时会遇到答案。

我将使用Gareth Rees在此处定义的迭代器模式堆栈来使用alecxe的答案:http://garethrees.org/2016/09/28/pattern/

代码,以防其他链接被破坏

def search(d, key, default=None):
    """
    Return a value corresponding to the specified key in the (possibly
    nested) dictionary d. If there is no item with that key, return
    default.
    """
    stack = [iter(d.items())]
    while stack:
        for k, v in stack[-1]:
            if isinstance(v, dict):
                stack.append(iter(v.items()))
                break
            elif k == key:
                return v
        else:
            stack.pop()
    return default

此代码使您可以避免超出某些其他解决方案中存在的最大递归深度的问题。

编辑:意识到您只是在试图找出字典中是否存在值。

您可以简单地将for循环修改为类似这样的内容,它应该可以用于简单的true / false搜索。

def search(d, key, default=False):
    """
    Return a value corresponding to the specified key in the (possibly
    nested) dictionary d. If there is no item with that key, return
    default.
    """
    stack = [iter(d.items())]
    while stack:
        for k, v in stack[-1]:
            if isinstance(v, dict):
                stack.append(iter(v.items()))
                break
            elif k == key:
                return True
            elif v == key:
                return True
        else:
            stack.pop()
    return default

答案 1 :(得分:0)

有一种可能更简单的方法,但是这就是我做过类似事情的方式。我已经为您的用例进行了修改。

import copy

def traverse_dict(_obj):
    _obj_2 = copy.deepcopy(_obj)
    if isinstance(_obj_2, dict):
        for key, value in _obj_2.items():
            if key == 'your_value':
                do_your_stuff()
            _obj_2[key] = traverse_dict(value)
    elif isinstance(_obj, list):
        for offset in range(len(_obj_2)):
            _obj_2[offset] = traverse_dict(_obj_2[offset])
    return _obj_2
相关问题