使用列表推导操作嵌套在列表中的dicts

时间:2018-01-25 10:36:36

标签: python

我有一个dicts列表,每个dict都有一个data键。每个数据键包含一组关于一个人的属性,这些属性都不是必需的:

persons = [
    {"Name": "John", "data": {"Age": 23, "Gender": "Male"}},
    {"Name": "Jane", "data": {"Age": 22, "Gender": "Female"}},
    {"Name": "Harry", "data": {"Age": 22}},
    {"Name": "Hermione", "data": {"Gender": "Female"}},
]

我想要做的是提取一个不同的年龄值列表。我已经这样做了:

ages = set()
persondatas = [person['data'] for person in persons]
for persondata in persondatas:
    if 'Age' in persondata:
        ages.add(persondata['Age'])
ages

返回:

  

{22,23}

这正是我想要的,但我认为必须有一个更好,更整洁的方式,而不是循环使用列表理解获得的列表。我可以在列表理解中完成所需的工作吗?我的第一次流产尝试是这样的: [person['data']['Age'] for person in l] 失败了:

  

KeyError:'年龄'

必须有一个更好的方法,但我已经摆弄,无法解决问题。有人可以帮忙吗?

3 个答案:

答案 0 :(得分:4)

你可以在你的列表理解中添加一个条件 - 用一个循环删除两个操作。

>>> {person['data']['Age'] for person in persons if 'Age' in person['data']}
set([22, 23])

注意我如何使用花括号({})而不是方括号([])来表示set comprehension

答案 1 :(得分:1)

试试这个:

ages = set([person["data"]["Age"] for person in persons if "Age" in person["data"]])

答案 2 :(得分:0)

一种解决方案是结合过滤器的列表理解。

set(filter(None, [p['data'].get('Age') for p in persons]))