首页 > 解决方案 > 如何在字典理解中填充可选字段?

问题描述

我正在编写一些代码,将具有非常详细信息的 json 数据库处理为更简单的格式。它复制一些字段并将其他字段重新序列化到一个新的 json 文件中。

我目前正在使用像这样的 MVCE 字典理解:

converted_data = {
    raw_item['name']: {
        'state': raw_item['field_a'],
        'variations': [variant for variant in raw_item['field_b']['variations']]
    } for raw_item in json.loads(my_file.read())
}

一个示例文件(不是正在使用的实际数据)是这样的:

[
    {
        "name": "Object A",
        "field_a": "foo",
        "field_b": {
            "bar": "baz",
            "variants": [
                "foo",
                "bar",
                "baz"
            ]
        }
    },
    {
        "name": "Object B",
        "field_a": "foo",
        "field_b": {
            "bar": "baz",
        }
    }
]

挑战在于并非所有项目都包含变化。我看到了两个潜在的解决方案:

  1. 使用 if 语句有条件地将variations字段应用到字典中。
  2. 为所有项目包括一个空白variations字段,如果原始项目包含变化,则填写它。

我可能会选择第二种解决方案。但是,有没有办法有条件地在字典理解中包含特定字段?


编辑:换句话说,方法1在字典理解中是否可行?

所需输出的示例(使用字典理解)如下所示:

{
    "Object A": {
        "state": "foo",
        "variants": ["foo", "bar", "baz"]
    },
    "Object B": {
        "state": "foo"
    }
}

我发现了一些其他有条件地更改条目过滤条目的问题,但这些问题不会无条件地创建一个项目,其中特定字段(在项目中)有条件地不存在。

标签: pythondictionary-comprehension

解决方案


我不确定您是否意识到您可以使用if内部分配,这对我来说似乎是一种非常干净的解决方法:

converted_data = {
    raw_item['name']: {
        'state': raw_item['field_a'],
        'variants': [] if 'variants' not in raw_item['field_b'] else
            [str(variant) for variant in raw_item['field_b']['variants']]
    } for raw_item in example
}

(注意:使用str()而不是初始示例中给出的未定义函数)

澄清问题后,这是添加不同字典的替代解决方案('variations'如果没有则缺少空键:

converted_data = {
    raw_item['name']: {
        'state': raw_item['field_a'],
        'variants': [str(variant) for variant in raw_item['field_b']['variants']]
    } if 'variants' in raw_item['field_b'] else {
        'state': raw_item['field_a'],
    } for raw_item in example
}

如果问题实际上是:字典文字中的键/值对可以是可选的(这将解决您的问题),那么答案就是“否”。但是对于这个简单的例子,上面的实现是相同的。

如果现实生活中的情况更复杂,只需按照此处给出的第一个解决方案构建字典,然后在构建后使用del(dictionary['key'])删除任何添加的具有None[]值的键。

例如,在第一个示例之后,converted_data可以使用以下命令进行清理:

for item in converted_data.values:
    if not item['variants']:
        del(item['variants'])

推荐阅读