【问题标题】:How do I pick specific values as I iterate through a list of dictionaries that contain nested dictionaries and lists?当我遍历包含嵌套字典和列表的字典列表时,如何选择特定值?
【发布时间】:2019-03-15 17:10:50
【问题描述】:

我试图在遍历包含嵌套字典和列表的字典列表时获取特定值。

这大致是我导入的 json 数据的样子(简化)。它是一个包含嵌套字典和嵌套列表的字典列表。

# What a single dictionary looks like prettified

[{ 'a':'1',
'b':'2',
'c':'3',
'd':{ 'ab':'12',
      'cd':'34',
      'ef':'56'},
'e':['test', 'list'],
'f':'etc...'
}]

# What the list of dictionaries looks like

dict_list = [{ 'a':'1', 'b':'2', 'c':'3', 'd':{ 'ab':'12','cd':'34', 'ef':'56'}, 'e':['test', 'list'], 'f':'etc...'}, { 'a':'2', 'b':'3', 'c':'4', 'd':{ 'ab':'23','cd':'45', 'ef':'67'}, 'e':['test2', 'list2'], 'f':'etcx2...'},{},........,{}]

这是我最初的代码,它只遍历字典列表。

for dic in dict_list:
    for val in dic.values():
        if not isinstance(val, dict):
            print(val)
        else:    
            for val2 in val.values():
                print (val2)

我上面的原始代码中的打印语句只是为了向我展示从字典列表中提取的内容。我想要做的是声明我希望从顶级和二级字典和列表中获取哪些值。

这是我正在寻找的输出作为示例。

列表中每个顶级字典的第一个键的值。

top_level_dict_key1 = ['1','2']

2 级字典的所有值。

level2_dic = ['12', '34', '56', '23', '45', '67']

或特定值。在这种情况下,每个嵌套字典中第一个键的值

level2_dict = ['12', '23']

嵌套列表中第二个键的值

level2_list = ['test', 'test2']

希望这很清楚。如果你也需要我,我会尽力澄清。

【问题讨论】:

  • 什么版本的 Python?在 3.7 之前,不保证字典有任何特定的顺序。
  • (顺便说一句,好的问题应该能够独立存在。如果您可以在不参考之前的问题的情况下对其进行编辑以使其有意义,那么任何试图帮助您的人都会更容易。)
  • 目前是 Python 3.6,但我可以为我的项目的这一部分运行使用 3.7 的环境。该项目的其余部分将是深度学习,因此 3.7 可能不是一个好主意。
  • @JETM 我发布的内容几乎就是我的其他问题的全部内容。我回过头来稍微编辑了这个,但没有太多新信息。有什么我想念的东西需要澄清吗?我很乐意帮忙。
  • 对您上一个问题的引用令人困惑。我看不到一个明确的问题。您可以删除所有关于以前有过这个问题的引用吗?

标签: python json dictionary


【解决方案1】:

对于Python 3.6的具体实现dictionaries happen to be ordered,但是依赖这种行为是不好的。除非订购,否则询问某事物的“第一个元素”是没有意义的,所以第一步是read the JSON into an OrderedDict

那么这只是一个仔细记账的问题。例如

import json                                                                     
from collections import OrderedDict                                             

dict_list = '[{ "a":"1", "b":"2", "c":"3", "d":{ "ab":"12","cd":"34", "ef":"56"}, "e":["test", "list"], "f":"etc..."}, { "a":"2", "b":"3", "c":"4", "d":{ "ab":"23"    ,"cd":"45", "ef":"67"}, "e":["test2", "list2"], "f":"etcx2..."}]'

dict_list = json.loads(dict_list, object_pairs_hook=OrderedDict)    
top_level_dict_key1 = []
level2_dic = []
level2_dict = []
level2_list = []
for dictionary in dict_list:
    top_level_dict_key1.append(list(dictionary.values())[0])
    for value in dictionary.values():
        if isinstance(value, OrderedDict):
            level2_dic.extend(list(value.values()))
            level2_dict.append(list(value.values())[0])
        elif isinstance(value, list):
            level2_list.append(value[0])

print(top_level_dict_key1)
print(level2_dic)
print(level2_dict)
print(level2_list)

输出:

['1', '2']
['12', '34', '56', '23', '45', '67']
['12', '23']
['test', 'test2']

(这可能不是最惯用的 Python 3 代码。当我不那么累的时候,我会编辑一些更好的东西。)

【讨论】:

  • 虽然我的示例数据似乎是有序的,但实际数据不是,对于这个项目,它并不一定重要,因为数据确实没有顺序,但我明白你在说什么。
  • 刚刚尝试了代码,但我收到了TypeError: 'dict_values' object does not support indexing 错误。这是 Python 3.6 的问题吗?
  • @MixedBeans 啊,我的错。我在 2.7 中测试过。您必须先将 .values() 转换为列表,然后才能对它们进行索引。或查看this 的回答以避免创建您不需要的列表。
  • 谢谢。我试了一下这段代码,发现我忘了使用 OrderedDict。我试图实现它,但我会得到一个错误。 TypeError: 'object_pairs_hook' is an invalid keyword argument for this function。这是我之前加载 json 的方式。 with open('test.json', 'r') as f: json_text = f.read() dict_list = json.loads(json_text) 我尝试删除 with open 并使用 dict_list = json.load(open('test.json')) ,这似乎加载正常但是当我添加 object_pairs_hook=OrderedDict 作为 json.load 的参数时,正如我在其他示例中看到的那样,我得到 TypeError
  • @MixedBeans Er... 仔细检查您是否将其传递给 json.load 而不是 open/ 拼写正确?我刚刚仔细检查了docs,它肯定在里面。
猜你喜欢
  • 2014-05-11
  • 2015-12-06
  • 2020-11-13
  • 1970-01-01
  • 2016-11-17
  • 1970-01-01
  • 2021-11-16
  • 2012-07-09
  • 2021-03-19
相关资源
最近更新 更多