【问题标题】:Removing mulitple key items with dict comprehension python使用dict理解python删除多个关键项目
【发布时间】:2019-06-27 13:22:44
【问题描述】:

我想从我的 json 中删除多个键,并且我正在使用这样的字典理解

remove_key = ['name', 'description']

    data = {'full-workflow': {'task_defaults': {'retry': {'count': 3, 'delay': 2}}, 'tasks': {'t1': {'action': 'nn.postgres.export-db', 'description': 'Dump prod DB with default settings', 'input': {'database': 'prod', 'filepath': '/var/tmp/prod-dump.pgsql', 'host': 'postgres.local', 'password': 'mypass', 'username': 'myuser'}, 'name': 'db export', 'on-success': ['t2']}, 't2': {'action': 'nn.aws.upload-to-s3', 'description': 'Upload to S3 bucket for development', 'input': {'sourcepath': '{{ tasks(t1).result.filepath }}', 'targetpath': 's3://mybucket/prod-dump.pgsql'}, 'name': 'Upload to S3', 'on-success': ['t3'], 'retry': {'count': 5, 'delay': 5}}, 't3': {'action': 'nn.shell.command', 'description': 'Remove temp file from batch folder ', 'input': {'cmd': 'rm {{ tasks(t1).result.filepath }}'}, 'name': 'Remove temp file', 'on-complete': ['t4']}, 't4': {'action': 'nn.notify.send-mail', 'description': 'Send email to admin containing target path', 'input': {'from': 'bot@nn.io', 'message': 'DB Dump {{ tasks(t1).result.filepath }} was stored to S3', 'subject': 'Prod DB Backup', 'to': 'admin@nn.io'}, 'name': 'Send email', 'target': 'nn'}}}, 'version': '2'}

    def remove_additional_key(data):
        return {
            key: data[key] for key in data if key not in remove_key
        }

那么就

new_data = remove_additional_key(data)

因为这是嵌套的dict,我想从tasks dict到remove_key,那我做错了什么?

【问题讨论】:

  • 您的主 data 字典中嵌套了多个字典。 namedescription 都是这些内部字典之一中的键,这就是它们没有被删除的原因。
  • 您的字典只有两个您正在迭代的键,full-workflowversion
  • 啊,好吧,嵌套字典,回到绘图板。
  • @PetarP 如果您对想要的操作有一个清晰的概念,您可以编辑您的问题。如果 namedescription 是任何嵌套字典中的键,是否要删除它们?
  • @yuvgin 我想从tasks中删除它们

标签: python python-3.x


【解决方案1】:

您的数据是嵌套字典。如果您想使用包含在remove_key 中的键删除任何数据,那么我建议采用递归方法。这可以根据您现有的函数remove_additional_key 轻松实现:

def remove_additional_key(data):

    sub_data = {} 
    for key in data:
        if key not in remove_key:
            if isinstance(data[key], dict): # if is dictionary
                sub_data[key] = remove_additional_key(data[key])
            else:
                sub_data[key] = data[key]
    return sub_data

new_data = remove_additional_key(data)

注意,如果条目是字典,可以通过isinstance(data[key], dict) 进行检查。见How to check if a variable is a dictionary in Python?

【讨论】:

  • isinstance 很好,不需要使用type 但这会删除完整的字典
  • 我测试过,当我在函数中传递我的dict时,输出dict是空的
  • 是的,我已经检查过了,谢谢你的改变,这个,你哪里更快:)
  • @PetarP 不客气。但请注意,您也应该考虑其他答案的建议。
  • 我会的,亚历克斯的建议和建议都被记录了,最糟糕的是我需要做更多的清洁工作,至少我有一个很好的基础可以玩
【解决方案2】:

您有一本包含几个嵌套字典的字典。如果您确切知道要删除哪些子词典,则可以使用:

data['full-workflow']['tasks']['t1'].pop('name')

在字典理解中使用查找方法 (key: data[key]) 效率低下,但是在如此小的数据量上您不会注意到差异。

如果您不知道嵌套字典的确切路径,可以使用一个函数(为方便起见,发布另一个 answer

def delete_keys_from_dict(d, lst_keys):
    for k in lst_keys:
        try:
            del dict_del[k]
        except KeyError:
            pass
    for v in dict_del.values():
        if isinstance(v, dict):
            delete_keys_from_dict(v, lst_keys)

    return dict_del

那你就可以打电话了

delete_keys_from_dict(data, ['name', 'description'])

不用说,如果你在多个嵌套字典中有name键,它们都会被删除,所以要小心。

【讨论】:

    猜你喜欢
    • 2012-01-16
    • 2017-09-23
    • 1970-01-01
    • 2016-03-26
    • 2014-07-21
    • 2021-11-20
    • 1970-01-01
    • 2020-07-30
    • 2022-08-04
    相关资源
    最近更新 更多