有更好的方法来清理字典吗?

时间:2016-04-01 23:00:48

标签: python python-3.x dictionary

我有dict,比如说这个

data={k:k for k in range(20)}

我对data的值进行了一些操作,有些操作为0,例如这个

for k,v in data.items():
    data[k] %= 2

执行此操作时,我想删除所有获取值为0的键,但是在飞行中执行会出错,所以我必须在最后执行此操作,因为我这样做

def clean(data):
    while True:
        try:
            for k,v in data.items():
                if not v:
                    del data[k]
            return
        except RuntimeError:
            pass

所以我的问题是:有一种更好的方法可以做到这一点,所以我将移动就地并避免使用额外的内存,并且更好地在一次旅行中?

编辑

这与我的预期用途类似

class MapDict(dict):

    def __repr__(self):
        return '{}({})'.format(self.__class__.__qualname__, super().__repr__())

    def map(self,func,*argv):
        '''applicate func to every value in this MapDict'''
        for k,v in self.items():
            self[k] = func(v,*argv)
        self.clean()

    def clean(self):
        while True:
            try:
                for k,v in self.items():
                    if not v:
                        del self[k]
                return
            except RuntimeError:
                pass


>>> data=MapDict( (k,k) for k in range(20) )
>>> data
MapDict({0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13, 14: 14, 15: 15, 16: 16, 17: 17, 18: 18, 19: 19})
>>> from operator import add, mod
>>> data.map(mod,2)
>>> data
MapDict({1: 1, 3: 1, 5: 1, 7: 1, 9: 1, 11: 1, 13: 1, 15: 1, 17: 1, 19: 1})
>>> data.map(add,10)
>>> data
MapDict({1: 11, 3: 11, 5: 11, 7: 11, 9: 11, 11: 11, 13: 11, 15: 11, 17: 11, 19: 11})
>>> 

这就是为什么我无法创建一个新的dict,并且我只希望在我的实例中仅保留相关值,以后我需要其他东西。

那么有更好的方法来干净吗?同时保持内存效率?并且在最少的旅行中?

3 个答案:

答案 0 :(得分:2)

在迭代时,不允许从字典中删除项目,但您可以迭代复制键(或项目):

for k in list(data):
    v = data[k]
    if not v:
        del data[k]

答案 1 :(得分:2)

在最小的内存使用情况下,您可以最快地删除动态的项目将是在第一次循环期间删除要删除的键列表,然后将其全部删除。然后,您只复制那些将被删除的密钥。

keys_to_del = []
for k, v in data.items():
    data[k] %= 2
    if data[k] == 0:
        keys_to_del.append(k)
for k in keys_to_del:
    del data[k]

答案 2 :(得分:1)

是否有必要这样做,如果没有:

def clean(data):
    return {k: v for k, v in data.items() if v}

如果是的话

def clean(data):
    remove_keys = tuple(k for k, v in data.items() if not v)
    for k in remove_keys:
        del data[k]