根据带有一个嵌套字典的键过滤字典列表

时间:2020-01-16 05:59:51

标签: python list dictionary

示例:

[{"a":{"x":13, "y":32, "z":33}, "b":5, "c":7, "d":8, "e":9}, {"a":{"x":18, "y":28, "z":38}, "b":57, "c":77, "d":87, "e":97}, {"a":{"x":17, "y":72, "z":73}, "b":58, "c":70, "d":80, "e":90}, ...]

这只是一个小样本集,但是我想要的是一个列表,其中包含每个字典中项目的过滤列表,如下所示:

样本输出:

[{"x":13, "b":5, "e"9}, {"x":18, "b":57, "e"97}, {"x":17, "b":58, "e"90}, ...]

我可以将其过滤为以下内容:

[{"a":{"x":13, "y":32, "z":33}, "b":5, "e":9}, {"a":{"x":18, "y":28, "z":38}, "b":57, "e":97}, {"a":{"x":17, "y":72, "z":73}, "b":58, "e":90}, ...]

使用以下代码

for i in range(len(results)):
    desired_keys = ['a', 'b', 'e']
    bigdict = all_results[i]
    filtered = {x: bigdict[x] for x in desired_keys if x in bigdict}

,但尚无法弄清楚如何将嵌套字典的一个元素取出来。

3 个答案:

答案 0 :(得分:2)

您不能仅使用您的方法,因为它仅适用于顶级密钥。您将需要指定每个键以及如何从嵌套字典中访问它:

>>> [{'x': e['a']['x'], 'b': e['b'], 'e': e['e']} for e in results]
[{'x': 13, 'b': 5, 'e': 9}, {'x': 18, 'b': 57, 'e': 97}, {'x': 17, 'b': 58, 'e': 90}, ...]

答案 1 :(得分:0)

如上所述,必须访问嵌套词典中的所有项目。

这种递归方法

keyword

产生

vals = [{"a":{"x":13, "y":32, "z":33}, "b":5, "c":7, "d":8, "e":9}, {"a":{"x":18, "y":28, "z":38}, "b":57, "c":77, "d":87, "e":97}, {"a":{"x":17, "y":72, "z":73}, "b":58, "c":70, "d":80, "e":90}]

def get_items(d, keys):
 res = dict()
 for k, v in d.items():
  if isinstance(v, dict):
   res.update(get_items(v, keys))
  elif k in keys:
   res[k] = v
 return res

r = [get_items(d, {'x','b', 'e'}) for d in vals]
print(r)

注意:确保键在嵌套字典的任何给定路径中都不会出现多次。

答案 2 :(得分:0)

具有生成器功能的另一种可能的递归方法:

def get_vals(d, to_find):
   for a, b in d.items():
     if a in to_find:
        yield (a, b)
     yield from [] if not isinstance(b, dict) else get_vals(b, to_find)

data = [{"a":{"x":13, "y":32, "z":33}, "b":5, "c":7, "d":8, "e":9}, {"a":{"x":18, "y":28, "z":38}, "b":57, "c":77, "d":87, "e":97}, {"a":{"x":17, "y":72, "z":73}, "b":58, "c":70, "d":80, "e":90}]
result = [dict(get_vals(i, ['x', 'b', 'e'])) for i in data]

输出:

[{'x': 13, 'b': 5, 'e': 9}, {'x': 18, 'b': 57, 'e': 97}, {'x': 17, 'b': 58, 'e': 90}]