我有一个字典的列表,其中一些值是空的:

d = {'a': [1], 'b': [1, 2], 'c': [], 'd':[]}

在创建这些列表的最后,我想在返回字典之前删除这些空列表。我试着这样做:

for i in d:
    if not d[i]:
        d.pop(i)

但是我得到了一个RuntimeError。我知道你不能在字典中添加/删除元素,而迭代它…那有什么解决办法呢?


请参阅在迭代Python字典时修改它,以了解这会导致问题的引用以及原因。


当前回答

嵌套的空值

假设我们有一个带有嵌套键的字典,其中一些键是空值:

dicti = {
"k0_l0":{
    "k0_l1": {
        "k0_l2": {
                "k0_0":None,
                "k1_1":1,
                "k2_2":2.2
                }
        },
        "k1_l1":None,
        "k2_l1":"not none",
        "k3_l1":[]
    },
    "k1_l0":"l0"
}

然后我们可以使用这个函数删除空值:

def pop_nested_nulls(dicti):
    for k in list(dicti):
        if isinstance(dicti[k], dict):
            dicti[k] = pop_nested_nulls(dicti[k])
        elif not dicti[k]:
            dicti.pop(k)
    return dicti

pop_nested_nulls(dicti)的输出

{'k0_l0': {'k0_l1': {'k0_l2': {'k1_1': 1,
                               'k2_2': 2.2}},
           'k2_l1': 'not '
                    'none'},
 'k1_l0': 'l0'}

其他回答

如果字典中的值也是唯一的,那么我使用这个解决方案:

keyToBeDeleted = None
for k, v in mydict.items():
    if(v == match):
        keyToBeDeleted = k
        break
mydict.pop(keyToBeDeleted, None)

嵌套的空值

假设我们有一个带有嵌套键的字典,其中一些键是空值:

dicti = {
"k0_l0":{
    "k0_l1": {
        "k0_l2": {
                "k0_0":None,
                "k1_1":1,
                "k2_2":2.2
                }
        },
        "k1_l1":None,
        "k2_l1":"not none",
        "k3_l1":[]
    },
    "k1_l0":"l0"
}

然后我们可以使用这个函数删除空值:

def pop_nested_nulls(dicti):
    for k in list(dicti):
        if isinstance(dicti[k], dict):
            dicti[k] = pop_nested_nulls(dicti[k])
        elif not dicti[k]:
            dicti.pop(k)
    return dicti

pop_nested_nulls(dicti)的输出

{'k0_l0': {'k0_l1': {'k0_l2': {'k1_1': 1,
                               'k2_2': 2.2}},
           'k2_l1': 'not '
                    'none'},
 'k1_l0': 'l0'}

对于Python 3:

{k:v for k,v in d.items() if v}

我会尽量避免在第一个位置插入空列表,但是,通常会使用:

d = {k: v for k,v in d.iteritems() if v} # re-bind to non-empty

如果在2.7之前:

d = dict( (k, v) for k,v in d.iteritems() if v )

或者是:

empty_key_vals = list(k for k in k,v in d.iteritems() if v)
for k in empty_key_vals:
    del[k]

这招对我很管用:

d = {1: 'a', 2: '', 3: 'b', 4: '', 5: '', 6: 'c'}
for key, value in list(d.items()):
    if value == '':
        del d[key]
print(d)
# {1: 'a', 3: 'b', 6: 'c'}

将字典项强制转换为list将创建其项的列表,因此可以遍历该列表并避免RuntimeError。