【发布时间】:2018-03-04 14:06:39
【问题描述】:
我对 python3 比较陌生,我正在尝试遍历现有的 OrderedDict() 以删除以 None 为值的条目。在 python2 中这不是问题,但据我了解,删除 dict.iteritems() (等等...)是由于返回 dict.items() 的方式发生了一些变化。
我 reeeeeeeeeeally 想避免复制字典...
我将要做(可能数百)数千个这样的操作,并且我不想将我使用的内存量增加一倍,只是为了从 OrderedDict 中删除空条目。
这是引发错误的代码:
class DefaultHeaders(OrderedDict):
def __init__(self, loop=None):
super(DefaultHeaders, self).__init__()
self['User-Agent'] = "Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:16.0.1) Gecko/20121011 Firefox/16.0.1" # <--(dummy User-Agent header for consistent response-format)
self['X-Search-ClientIP'] = gethostbyname(gethostname())
self['X-MSEdge-ClientID'] = None
self['Accept'] = None
self['Accept-Language'] = None
self['X-Search-Location'] = None
self._clean1() # <--raises error
# self._clean2() # <--raises error
# self._clean3() # <--raises error
def _clean1(self):
for k, v in self.items():
if k in ('count', 'offset'):
pass
elif not v: del self[k]
def _clean2(self):
for k, v in list(self.items()):
if k in ('count', 'offset'):
pass
elif not v: del self[k]
def _clean3(self):
_iter_this = list(self.items())
for k, v in _iter_this:
if k in ('count', 'offset'):
pass
elif not v: del self[k]
这是我得到的错误:
...
for k, v in self.items():
RuntimeError: OrderedDict mutated during iteration
Process finished with exit code 1
【问题讨论】:
-
复制 OrderedDict 不会使内存使用量翻倍。这只会复制 OrderedDict 本身,而不是它的键或值。复制它。
-
你能扩展一下吗?实例化一个新的类实例不会带来开销吗?
-
"实例化一个新的类实例不会带来开销吗?" - 是的,但是这个开销比你想象的要小得多。
-
另外,
_clean2和_clean3不应该引发错误。 -
当你清理字典时,你会得到一个副本。完成清理后,可以丢弃副本并回收其内存。由于您一次只会清理一个字典,因此您不需要一次保留多个字典的副本。
标签: python python-3.x dictionary iteration ordereddictionary