他说,在蒂姆·彼得(Tim Peter)的回答中,“是否有任何理由不使用有序词典”
OrderedDict是dict的子类。 它并没有慢很多,但是至少比使用普通字典要多一倍的内存。
OrderedDict是dict的子类。
它并没有慢很多,但是至少比使用普通字典要多一倍的内存。
现在,当遇到一个特定问题时,我尝试使用进行了一些示例检查ipython,但它们都与先前的推理相矛盾:
ipython
dict
OrderedDict
有人可以向我解释我的推理哪里出问题了吗?
import sys import random from collections import OrderedDict test_dict = {} test_ordered_dict = OrderedDict() for key in range(10000): test_dict[key] = random.random() test_ordered_dict[key] = random.random() sys.getsizeof(test_dict) 786712 sys.getsizeof(test_ordered_dict) 786712
%timeit
import sys import random from collections import OrderedDict def operate_on_dict(r): test_dict = {} for key in range(r): test_dict[key] = random.random() def operate_on_ordered_dict(r): test_ordered_dict = OrderedDict() for key in range(r): test_ordered_dict[key] = random.random() %timeit for x in range(100): operate_on_ordered_dict(100) 100 loops, best of 3: 9.24 ms per loop %timeit for x in range(100): operate_on_dict(100) 1000 loops, best of 3: 1.23 ms per loop
我认为大小的问题是由于__sizeof__在Python 2.X的实现中OrderedDict没有定义方法的事实,所以它只是退回到dict的__sizeof__方法。
__sizeof__
为了在这里证明这一点,我在这里创建了一个A扩展的类,list并且还添加了一个额外的方法foo来检查是否影响大小。
A
list
foo
class A(list): def __getitem__(self, k): return list.__getitem__(self, k) def foo(self): print 'abcde' >>> a = A(range(1000)) >>> b = list(range(1000))
但仍返回相同的大小sys.getsizeof:
sys.getsizeof
>>> sys.getsizeof(a), sys.getsizeof(b) (9120, 9120)
当然A会很慢,因为它的方法在Python中运行,而list的方法将在纯C中运行。
>>> %%timeit ... for _ in xrange(1000): ... a[_] ... 1000 loops, best of 3: 449 µs per loop >>> %%timeit for _ in xrange(1000): b[_] ... 10000 loops, best of 3: 52 µs per loop
这似乎在Python 3中已得到修复,该Python 3中现在有一个定义明确的__sizeof__方法:
def __sizeof__(self): sizeof = _sys.getsizeof n = len(self) + 1 # number of links including root size = sizeof(self.__dict__) # instance dictionary size += sizeof(self.__map) * 2 # internal dict and inherited dict size += sizeof(self.__hardroot) * n # link objects size += sizeof(self.__root) * n # proxy objects return size