[Python-checkins] r70012 - peps/trunk/pep-0372.txt

raymond.hettinger python-checkins at python.org
Fri Feb 27 05:32:12 CET 2009


Author: raymond.hettinger
Date: Fri Feb 27 05:32:11 2009
New Revision: 70012

Log:
Update PEP based on latest version of recipe, based on integration testing, and based on newsgroup feedback.

Modified:
   peps/trunk/pep-0372.txt

Modified: peps/trunk/pep-0372.txt
==============================================================================
--- peps/trunk/pep-0372.txt	(original)
+++ peps/trunk/pep-0372.txt	Fri Feb 27 05:32:11 2009
@@ -143,22 +143,19 @@
     This behavior is consistent with existing implementations in
     Python, the PHP array and the hashmap in Ruby 1.9.
 
-Why is there no ``odict.insert()``?
-
-    There are few situations where you really want to insert a key at
-    a specified index.  To avoid API complication, the proposed
-    solution for this situation is creating a list of items,
-    manipulating that and converting it back into an odict:
-
-    >>> d = odict([('a', 42), ('b', 23), ('c', 19)])
-    >>> l = d.items()
-    >>> l.insert(1, ('x', 0))
-    >>> odict(l)
-    collections.odict([('a', 42), ('x', 0), ('b', 23), ('c', 19)])
-
-Is the ordered dict a dict subclass?
+Is the ordered dict a dict subclass?  Why?
 
     Yes.  Like ``defaultdict``, ``odict`` subclasses ``dict``.
+    Being a dict subclass confers speed upon methods that aren't overridden
+    like ``__getitem__`` and ``__len__``.   Also, being a dict gives the
+    most utility with tools that were expecting regular dicts (like the
+    json module).
+
+Do any limitations arise from subclassing dict?
+
+    Yes.  Since the API for dicts is different in Py2.x and Py3.x, the
+    odict API must also be different (i.e. Py2.6 needs to override
+    iterkeys, itervalues, and iteritems).
 
 Does ``odict.popitem()`` return a particular key/value pair?
 
@@ -166,8 +163,8 @@
     corresponding value.  This corresponds to the usual LIFO behavior
     exhibited by traditional push/pop pairs.  It is semantically
     equivalent to ``k=list(od)[-1]; v=od[k]; del od[k]; return (k,v)``.
-    The actual implementation is more efficient.  It is O(n log n)
-    on the first call, any successive calls are O(1).
+    The actual implementation is more efficient and pops directly
+    off of a sorted list of keys.
     
 Does odict support indexing, slicing, and whatnot?
 
@@ -184,6 +181,50 @@
    dbm) is likely a better fit.   It would be a mistake to try to be all
    things to all users.
 
+How well does odict work with the json module and PyYAML?
+
+   For json, the good news is that json's encoder respects odict's iteration order:
+
+        >>> items = [('one', 1), ('two', 2), ('three',3), ('four',4), ('five',5)]
+        >>> json.dumps(OrderedDict(items))
+        '{"one": 1, "two": 2, "three": 3, "four": 4, "five": 5}'
+
+   The bad news is that the object_hook for json decoders will pass in an
+   already built dictionary so that the order is lost before the object
+   hook sees it:
+
+        >>> jtext = '{"one": 1, "two": 2, "three": 3, "four": 4, "five": 5}'
+        >>> json.loads(jtext, object_hook=OrderedDict)
+        OrderedDict({u'four': 4, u'three': 3, u'five': 5, u'two': 2, u'one': 1})
+
+   For PyYAML, a full round-trip is problem free:
+
+        >>> ytext = yaml.dump(OrderedDict(items))
+        >>> print ytext
+        !!python/object/apply:collections.OrderedDict
+        - - [one, 1]
+          - [two, 2]
+          - [three, 3]
+          - [four, 4]
+          - [five, 5]
+
+        >>> yaml.load(ytext)
+        OrderedDict({'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5})
+
+How does odict handle equality testing?
+
+   Being a dict, one might expect equality tests to not care about order.  For
+   an odict to dict comparison, this would be a necessity and it's probably
+   not wise to silently switch comparison modes based on the input types.
+   Also, some third-party tools that expect dict inputs may also expect the
+   comparison to not care about order.  Accordingly, we decided to punt and
+   let the usual dict equality testing run without reference to internal
+   ordering.  This should be documented clearly since different people will
+   have different expectations.  If a use case does arise, it's not hard to
+   explicitly craft an order based comparison:
+   ``list(od1.items())==list(od2.items())``.
+
+
 Reference Implementation
 ========================
 


More information about the Python-checkins mailing list