【问题标题】:Remove empty string keys from nested dictionary, dict comprehension从嵌套字典中删除空字符串键,字典理解
【发布时间】:2019-09-17 07:37:21
【问题描述】:

这行得通:

def delete_empty_keys(d):

    new_d = {}
    for key,value in d.items():
        if key != '' and not isinstance(value, dict):
            new_d[key] = value
        elif key != '' and isinstance(value, dict):
            new_d[key] = delete_empty_keys(value)
        else:
            pass
    return new_d

如何把它变成一个 dict 理解?我已经尝试过了,但我无法让它工作,最后我应该有一个else pass

def delete_empty_keys(d):
    return {key: value
    if key != '' and not isinstance(value, dict)
    else delete_empty_keys(value)
    if key != '' and isinstance(value, dict)
    #else pass??
    for key, value in d.items()
    }

【问题讨论】:

  • 请提供示例输入和预期输出
  • 注意:您不是在过滤None 键,而是在过滤空字符串。

标签: python dictionary dictionary-comprehension


【解决方案1】:

你的循环

for key,value in d.items():
    if key != '' and not isinstance(value, dict):
        new_d[key] = value
    elif key != '' and isinstance(value, dict):
        new_d[key] = delete_empty_keys(value)
    else:
        pass

实际上只是测试是否应该跳过键,如果不是,如何处理该值。如果把关键测试抽出来单独if语句,可以改写为

for key, value in d.items():
    if key != '':
        if not isinstance(value, dict):
            new_d[key] = value
        else:
            new_d[key] = delete_empty_keys(value)

所以if key != '': 测试实际上是在过滤项目,选择哪些应该是新字典的一部分。理解中的过滤是在循环中使用额外的 if 组件完成的:

<item> for <target> in <iterable> if <test>  # optional: more for loops and if tests

if &lt;test&gt; 部分过滤可迭代对象,限制使用的项目。在字典理解中使用相同的内容。

这留下了内部if...else 测试,可以用条件表达式表示(在两个选项之间进行选择):

# iteration, for <target> in <iterable>
for key, value in d.items():
    # filter, if <test>
    if key != '':
        # <item>, here a <key> and <value> expression for the dict comprehension
        new_d[key] = value if not isinstance(value, dict) else delete_empty_keys(value)

现在你有了一个可以转化为字典理解的表单:

{
    key: value if not isinstance(value, dict) else delete_empty_keys(value)
    for key, value in d.items()
    if key != ''
}

或者,在你的函数中:

def delete_empty_keys(d):
    return {key: value if not isinstance(value, dict) else delete_empty_keys(value)
            for key, value in d.items() if key != ''}

【讨论】:

  • 值得指出的是,虽然这可行,但它可能不是首选 - 复杂的理解通常比带有条件的 for 循环可读性差。尽管如此,还是很好的答案。
  • 是的,写的时候才意识到!谢谢楼主!
  • @DeveshKumarSingh:不过,这不需要添加到我的答案中。
【解决方案2】:

好吧,如果你真的想要这样做:

def delete_empty_keys(d):
    return {k: delete_empty_keys(v) if isinstance(v, dict) 
            else v 
            for k, v in d.items() if k != ''}

例子:

d = {'': 'delete_me',
     'a': {'': {'delete': 'me',
                'me': 'too'},
           'dont': 'delete_me',
           'keep': 'me'},
     'b': {'': 'bye'},
     'c': 'not_nested'}

delete_empty_keys(d)

输出:

{'a': {'dont': 'delete_me', 'keep': 'me'}, 'b': {}, 'c': 'not_nested'}

你不会在dict 理解中使用pass,因为pass 不会返回任何内容。理解中的所有内容都应该返回一些东西。

另外,如评论中所述:None != ''

【讨论】:

    猜你喜欢
    • 2017-03-08
    • 2021-07-24
    • 2019-11-18
    • 2018-04-14
    • 2013-11-30
    • 2021-09-18
    • 2014-01-19
    • 1970-01-01
    相关资源
    最近更新 更多