diff --git a/pep-0372.txt b/pep-0372.txt index de4d79de8..172cacef5 100644 --- a/pep-0372.txt +++ b/pep-0372.txt @@ -122,18 +122,12 @@ Questions and Answers What happens if an existing key is reassigned? The key is not moved but assigned a new value in place. This is - consistent with existing implementations and allows subclasses to - change the behavior easily:: - - class moving_odict(collections.odict): - def __setitem__(self, key, value): - self.pop(key, None) - collections.odict.__setitem__(self, key, value) + consistent with existing implementations. What happens if keys appear multiple times in the list passed to the constructor? - The same as for regular dicts: The latter item overrides the + The same as for regular dicts -- the latter item overrides the former. This has the side-effect that the position of the first key is used because only the value is actually overwritten:: @@ -145,17 +139,17 @@ constructor? 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). + Yes. Like ``defaultdict``, an ordered dictionary `` subclasses ``dict``. + Being a dict subclass make some of the methods faster (like + ``__getitem__`` and ``__len__``). More importantly, being a dict + subclass lets ordered dictionaries be usable with tools like json that + insist on having dict inputs by testing isinstance(d, dict). 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). + odict API must also be different. So, the Py2.7 version will need + to override iterkeys, itervalues, and iteritems. Does ``odict.popitem()`` return a particular key/value pair? @@ -164,22 +158,21 @@ Does ``odict.popitem()`` return a particular key/value pair? 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 and pops directly - off of a sorted list of keys. + from a sorted list of keys. Does odict support indexing, slicing, and whatnot? As a matter of fact, ``odict`` does not implement the ``Sequence`` interface. Rather, it is a ``MutableMapping`` that remembers the order of key insertion. The only sequence-like addition is - automatic support for ``reversed``. + support for ``reversed``. Does odict support alternate sort orders such as alphabetical? No. Those wanting different sort orders really need to be using another technique. The odict is all about recording insertion order. If any other order is of interest, then another structure (like an in-memory - dbm) is likely a better fit. It would be a mistake to try to be all - things to all users. + dbm) is likely a better fit. How well does odict work with the json module, PyYAML, and ConfigParser? @@ -213,7 +206,7 @@ How well does odict work with the json module, PyYAML, and ConfigParser? >>> yaml.load(ytext) OrderedDict({'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5}) - For the ConfigParser module, round-tripping is problem free. Custom + For the ConfigParser module, round-tripping is also problem free. Custom dicts were added in Py2.6 specifically to support ordered dictionaries:: >>> config = ConfigParser(dict_type=OrderedDict) @@ -224,21 +217,23 @@ How well does odict work with the json module, PyYAML, and ConfigParser? 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 + 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())``. + have different expectations. If a use case does arise, it's not hard for + a user explicitly craft an order based comparison:: + + # Explict order-sensitive comparison + >>> list(od1.items())==list(od2.items()) What are the trade-offs of the possible underlying data structures? - * Keeping a sorted list of keys is very fast for all operations except - __delitem__() which becomes an O(n) exercise. This structure leads to - very simple code and little wasted space. + * Keeping a sorted list of keys is fast for all operations except + __delitem__() which becomes an O(n) exercise. This data structure leads + to very simple code and little wasted space. * Keeping a separate dictionary to record insertion sequence numbers makes the code a little bit more complex. All of the basic operations are O(1)