天天看點

python dict實作原理_Python_OrderedDict原理

class OrderedDict(dict):

'Dictionary that remembers insertion order'

# An inherited dict maps keys to values.

# The inherited dict provides __getitem__, __len__, __contains__, and get.

# The remaining methods are order-aware.

# Big-O running times for all methods are the same as regular dictionaries.

# The internal self.__map dict maps keys to links in a doubly linked list.

# The circular doubly linked list starts and ends with a sentinel element.

# The sentinel element never gets deleted (this simplifies the algorithm).

# Each link is stored as a list of length three: [PREV, NEXT, KEY].

def __init__(*args, **kwds):

'''Initialize an ordered dictionary. The signature is the same as

regular dictionaries, but keyword arguments are not recommended because

their insertion order is arbitrary.

note:

root[:];

__map

'''

if not args:

raise TypeError("descriptor '__init__' of 'OrderedDict' object "

"needs an argument")

self = args[0] # 執行個體

args = args[1:] # 鍵值對

if len(args) > 1:

raise TypeError('expected at most 1 arguments, got %d' % len(args))

try:

self.__root

except AttributeError:

self.__root = root = [] # sentinel node

root[:] = [root, root, None]

self.__map = {}

self.__update(*args, **kwds)

def __setitem__(self, key, value, dict_setitem=dict.__setitem__):

# 添加新元素時,在連結清單尾部建立新連結清單,并使用新鍵值對更新字典

'od.__setitem__(i, y) <==> od[i]=y'

# Setting a new item creates a new link at the end of the linked list,

# and the inherited dictionary is updated with the new key/value pair.

if key not in self:

root = self.__root

last = root[0] # 頭節點的前驅節點

last[1] = root[0] = self.__map[key] = [last, root, key] # key的前驅節點為last,後繼節點為root利用self.__map來定位key

return dict_setitem(self, key, value)

def __delitem__(self, key, dict_delitem=dict.__delitem__):

'od.__delitem__(y) <==> del od[y]'

# Deleting an existing item uses self.__map to find the link which gets

# removed by updating the links in the predecessor and successor nodes.

dict_delitem(self, key)

link_prev, link_next, _ = self.__map.pop(key)

link_prev[1] = link_next # update link_prev[NEXT]

link_next[0] = link_prev # update link_next[PREV]

def __iter__(self):

'od.__iter__() <==> iter(od)'

# Traverse the linked list in order.

root = self.__root

curr = root[1] # start at the first node

while curr is not root: # 每個節點包含三大部分

yield curr[2] # yield the curr[KEY]

curr = curr[1] # move to next node

def __reversed__(self):

'od.__reversed__() <==> reversed(od)'

# Traverse the linked list in reverse order.

root = self.__root

curr = root[0] # start at the last node

while curr is not root:

yield curr[2] # yield the curr[KEY]

curr = curr[0] # move to previous node

def clear(self):

'od.clear() -> None. Remove all items from od.'

root = self.__root

root[:] = [root, root, None]

self.__map.clear()

dict.clear(self)