![](/img/trans.png)
[英]Can I convert a defaultdict or dict to an ordereddict in Python?
[英]OrderedDict vs Dict in python
在蒂姆彼得的答案中 ,“有沒有理由不使用有序詞典”,他說
OrderedDict是dict的子類。
它的速度並不慢很多,但至少使用普通字典使內存翻倍。
現在,在經歷一個特定的問題時 ,我嘗試使用ipython
一些樣本檢查,並且兩者都與之前的推理相矛盾:
dict
和OrderedDict
的大小相同 OrderedDict
上操作比在dict
上操作時容易大約7-8倍(因此慢很多) 有人可以向我解釋我在推理中出錯的地方嗎?
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
我認為大小的問題是由於在OrderedDict
Python 2.X 實現中沒有定義__sizeof__
方法的事實,所以它簡單地回退到dict的__sizeof__
方法。
為了證明這一點,我在這里創建了一個類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(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中修復的,現在有一個定義良好的__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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.