【问题标题】:Find all occurrence of keys in nested python dict在嵌套的python dict中查找所有出现的键
【发布时间】:2019-11-12 02:33:54
【问题描述】:

我有一本这样的字典:

a = {'compatibility': {'schema': ['attribute_variables/evar44',
   'event42',
   'container_visitors'],
  'status': 'valid',
  'supported_features': ['function_and',
   'function_attr',
   'function_container',
   'function_event',
   'function_event-exists',
   'function_streq'],
  'supported_products': ['o', 'data_warehouse', 'discover'],
  'supported_schema': ['warehouse', 'n'],
  'validator_version': '1.1.11'},
 'definition': {'container': {'context': 'visitors',
   'func': 'container',
   'pred': {'func': 'and',
    'preds': [{'description': 'e42',
      'evt': {'func': 'event', 'name': 'metrics/event42'},
      'func': 'event-exists'},
     {'description': 'v44',
      'func': 'streq',
      'str': '544',
      'val': {'func': 'attr', 'name': 'variables/evar44'}}]}},
  'func': 'segment',
  'version': [1, 0, 0]},
 'description': '',
 'id': 's2165c30c946ebceb',
 'modified': '12',
 'name': 'Apop',
 'owner': {'id': 84699, 'login': 'max', 'name': 'Max'},
 'reportSuiteName': 'App',
 'rsid': 'test',
 'siteTitle': 'App',
 'tags': []}

我想提取每个键“description”、“func”和“str”/“num”的值,并在这些dict的一个DataFrame中返回这些值。

我用这段代码尝试过,但我无法获得每个值,也无法将这些值放在一个 DataFrame 中。

def findkeys(node, kv):
    if isinstance(node, list):
        for i in node:
            for x in findkeys(i, kv):
               yield x
    elif isinstance(node, dict):
        if kv in node:
            yield node[kv]
        for j in node.values():
            for x in findkeys(j, kv):
                yield x

对于我的示例,我想要的输出:

pd.DataFrame(np.array([['e42', 'event', 'NaN'], ['v44', 'streq', '544']]), 
               columns=['description', 'funk', 'str/num'])

【问题讨论】:

  • 这些信息总是一致的吗?我的意思是,该数据是通过关注a['definition']['container']['pred']['preds'] 找到的。如果它总是在那里,您可以遍历该列表。
  • 还有什么让它变得棘手,是否有嵌套/多个 "func" 键,所以说你想提取每个键 "func" 的所有值,你将无法得到你正在寻找的结果。
  • 不幸的是,数据不一致,它可以通过 a['definition']['container']['pred']['preds'] 或 a['definition'] 找到['容器']['pred']['evt']

标签: python json dataframe dictionary


【解决方案1】:

下面的代码将“有趣”键的值收集到一个字典中。

from collections import defaultdict

a = {'compatibility': {'schema': ['attribute_variables/evar44',
                                  'event42',
                                  'container_visitors'],
                       'status': 'valid',
                       'supported_features': ['function_and',
                                              'function_attr',
                                              'function_container',
                                              'function_event',
                                              'function_event-exists',
                                              'function_streq'],
                       'supported_products': ['o', 'data_warehouse', 'discover'],
                       'supported_schema': ['warehouse', 'n'],
                       'validator_version': '1.1.11'},
     'definition': {'container': {'context': 'visitors',
                                  'func': 'container',
                                  'pred': {'func': 'and',
                                           'preds': [{'description': 'e42',
                                                      'evt': {'func': 'event', 'name': 'metrics/event42'},
                                                      'func': 'event-exists'},
                                                     {'description': 'v44',
                                                      'func': 'streq',
                                                      'str': '544',
                                                      'val': {'func': 'attr', 'name': 'variables/evar44'}}]}},
                    'func': 'segment',
                    'version': [1, 0, 0]},
     'description': '',
     'id': 's2165c30c946ebceb',
     'modified': '12',
     'name': 'Apop',
     'owner': {'id': 84699, 'login': 'max', 'name': 'Max'},
     'reportSuiteName': 'App',
     'rsid': 'test',
     'siteTitle': 'App',
     'tags': []}


def walk_dict(d, interesting_keys, result, depth=0):
    for k, v in sorted(d.items(), key=lambda x: x[0]):
        if isinstance(v, dict):
            walk_dict(v, interesting_keys, result, depth + 1)
        elif isinstance(v,list):
            for entry in v:
                if isinstance(entry, dict):
                    walk_dict(entry, interesting_keys, result, depth + 1)
        else:
            if k in interesting_keys:
                result[k].append(v)


result = defaultdict(list)
walk_dict(a, ["description", "func", "str", "num"], result)
print(result)

输出

defaultdict(<class 'list'>, {'func': ['container', 'and', 'event', 'event-exists', 'streq', 'attr', 'segment'], 'description': ['e42', 'v44', ''], 'str': ['544']})

【讨论】:

    猜你喜欢
    • 2012-04-06
    • 1970-01-01
    • 2012-03-08
    • 2017-12-05
    • 2020-06-17
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    相关资源
    最近更新 更多