Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
f173654d
Commit
f173654d
authored
Mar 23, 2009
by
Raymond Hettinger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Forward port r70533 and r70538.
parent
30364204
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
45 additions
and
32 deletions
+45
-32
Lib/collections.py
Lib/collections.py
+45
-32
No files found.
Lib/collections.py
View file @
f173654d
...
@@ -11,74 +11,87 @@ from operator import itemgetter as _itemgetter
...
@@ -11,74 +11,87 @@ from operator import itemgetter as _itemgetter
from
keyword
import
iskeyword
as
_iskeyword
from
keyword
import
iskeyword
as
_iskeyword
import
sys
as
_sys
import
sys
as
_sys
import
heapq
as
_heapq
import
heapq
as
_heapq
from
weakref
import
proxy
from
itertools
import
repeat
as
_repeat
,
chain
as
_chain
,
starmap
as
_starmap
from
itertools
import
repeat
as
_repeat
,
chain
as
_chain
,
starmap
as
_starmap
################################################################################
################################################################################
### OrderedDict
### OrderedDict
################################################################################
################################################################################
class
_Link
(
object
):
__slots__
=
'prev'
,
'next'
,
'key'
,
'__weakref__'
class
OrderedDict
(
dict
,
MutableMapping
):
class
OrderedDict
(
dict
,
MutableMapping
):
'Dictionary that remembers insertion order'
'Dictionary that remembers insertion order'
# The inherited dict maps keys to values.
# An inherited dict maps keys to values.
# The internal self.__map dictionary maps keys to links in a doubly linked list.
# The doubly linked list starts and ends with a sentinel element.
# The sentinel element never gets deleted. It simplifies the algorithm.
# Setting a new item causes a new link to append to the doubly linked list.
# Deleting an item uses self.__map to find the link, which is then removed.
# Iteration follows the linked list in order.
# Reverse iteration follows the links backwards.
# The inherited dict provides __getitem__, __len__, __contains__, and get.
# The inherited dict provides __getitem__, __len__, __contains__, and get.
# The remaining methods are order-aware.
# The remaining methods are order-aware.
# Big-Oh running times for all methods are the same as for regular dictionaries.
# Big-O running times for all methods are the same as for regular dictionaries.
# The internal self.__map dictionary 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).
# The prev/next links are weakref proxies (to prevent circular references).
# Individual links are kept alive by the hard reference in self.__map.
# Those hard references disappear when a key is deleted from an OrderedDict.
def
__init__
(
self
,
*
args
,
**
kwds
):
def
__init__
(
self
,
*
args
,
**
kwds
):
if
len
(
args
)
>
1
:
if
len
(
args
)
>
1
:
raise
TypeError
(
'expected at most 1 arguments, got %d'
%
len
(
args
))
raise
TypeError
(
'expected at most 1 arguments, got %d'
%
len
(
args
))
try
:
try
:
self
.
__
end
self
.
__
root
except
AttributeError
:
except
AttributeError
:
self
.
__root
=
_Link
()
# sentinel node for the doubly linked list
self
.
clear
()
self
.
clear
()
self
.
update
(
*
args
,
**
kwds
)
self
.
update
(
*
args
,
**
kwds
)
def
clear
(
self
):
def
clear
(
self
):
self
.
__end
=
end
=
[]
root
=
self
.
__root
end
+=
[
None
,
end
,
end
]
# sentinel node for doubly linked lis
t
root
.
prev
=
root
.
next
=
roo
t
self
.
__map
=
{}
# key --> [key, prev, next]
self
.
__map
=
{}
dict
.
clear
(
self
)
dict
.
clear
(
self
)
def
__setitem__
(
self
,
key
,
value
):
def
__setitem__
(
self
,
key
,
value
):
# Setting a new item creates a new link which goes at the end of the linked
# list, and the inherited dictionary is updated with the new key/value pair.
if
key
not
in
self
:
if
key
not
in
self
:
end
=
self
.
__end
self
.
__map
[
key
]
=
link
=
_Link
()
curr
=
end
[
1
]
root
=
self
.
__root
curr
[
2
]
=
end
[
1
]
=
self
.
__map
[
key
]
=
[
key
,
curr
,
end
]
last
=
root
.
prev
link
.
prev
,
link
.
next
,
link
.
key
=
last
,
root
,
key
last
.
next
=
root
.
prev
=
proxy
(
link
)
dict
.
__setitem__
(
self
,
key
,
value
)
dict
.
__setitem__
(
self
,
key
,
value
)
def
__delitem__
(
self
,
key
):
def
__delitem__
(
self
,
key
):
# Deleting an existing item uses self.__map to find the link which is
# then removed by updating the links in the predecessor and successor nodes.
dict
.
__delitem__
(
self
,
key
)
dict
.
__delitem__
(
self
,
key
)
key
,
prev
,
next
=
self
.
__map
.
pop
(
key
)
link
=
self
.
__map
.
pop
(
key
)
prev
[
2
]
=
next
link
.
prev
.
next
=
link
.
next
next
[
1
]
=
prev
link
.
next
.
prev
=
link
.
prev
def
__iter__
(
self
):
def
__iter__
(
self
):
end
=
self
.
__end
# Traverse the linked list in order.
curr
=
end
[
2
]
# start at first link
root
=
self
.
__root
while
curr
is
not
end
:
curr
=
root
.
next
yield
curr
[
0
]
# yield KEY for each link
while
curr
is
not
root
:
curr
=
curr
[
2
]
# goto next link
yield
curr
.
key
curr
=
curr
.
next
def
__reversed__
(
self
):
def
__reversed__
(
self
):
end
=
self
.
__end
# Traverse the linked list in reverse order.
curr
=
end
[
1
]
# start at last link
root
=
self
.
__root
while
curr
is
not
end
:
curr
=
root
.
prev
yield
curr
[
0
]
# yield KEY for each link
while
curr
is
not
root
:
curr
=
curr
[
1
]
# goto prev link
yield
curr
.
key
curr
=
curr
.
prev
def
__reduce__
(
self
):
def
__reduce__
(
self
):
items
=
[[
k
,
self
[
k
]]
for
k
in
self
]
items
=
[[
k
,
self
[
k
]]
for
k
in
self
]
tmp
=
self
.
__map
,
self
.
__
end
tmp
=
self
.
__map
,
self
.
__
root
del
self
.
__map
,
self
.
__
end
del
self
.
__map
,
self
.
__
root
inst_dict
=
vars
(
self
).
copy
()
inst_dict
=
vars
(
self
).
copy
()
self
.
__map
,
self
.
__
end
=
tmp
self
.
__map
,
self
.
__
root
=
tmp
if
inst_dict
:
if
inst_dict
:
return
(
self
.
__class__
,
(
items
,),
inst_dict
)
return
(
self
.
__class__
,
(
items
,),
inst_dict
)
return
self
.
__class__
,
(
items
,)
return
self
.
__class__
,
(
items
,)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment