PEP 372 -- Adding an ordered directory to collections ready for pronouncement
Hi everybody, PEP 372 was modified so that it provides a simpler API (only the dict API to be exact) and it was decided to start with a Python-only implementation and replace it with a C version later if necessary. Annotated changes from earlier versions of the PEP: - the extra API for ordered dict was dropped to keep the interface simple and clean. Future versions can still be expanded but it's impossible to drop features later on. - To keep the implementation simple 3.1 / 2.7 will ship with a Python-only version of the class. It can still be rewritten in C if it turns out to be too slow or thread safety is required. The corresponding issue in the tracker: http://bugs.python.org/issue5397 Link to the PEP: http://www.python.org/dev/peps/pep-0372/ Anything else that should be done? Regards, Armin
On Sun, 1 Mar 2009 19:13:27 +0000 (UTC), Armin Ronacher <armin.ronacher@active-4.com> wrote:
Hi everybody,
PEP 372 was modified so that it provides a simpler API (only the dict API to be exact) and it was decided to start with a Python-only implementation and replace it with a C version later if necessary.
Annotated changes from earlier versions of the PEP:
- the extra API for ordered dict was dropped to keep the interface simple and clean. Future versions can still be expanded but it's impossible to drop features later on.
Keeping the API simple and clean sounds great. I'm all in favor of this. However, it does no one a service to continue to propagate the idea that all the code written for Python always has to be perfect. It's feasible and even simple to drop features later on, should it turn out to be that they are not desirable. Jean-Paul
[Armin Ronacher]
PEP 372 was modified so that it provides a simpler API (only the dict API to be exact) and it was decided to start with a Python-only implementation and replace it with a C version later if necessary.
Annotated changes from earlier versions of the PEP:
- the extra API for ordered dict was dropped to keep the interface simple and clean. Future versions can still be expanded but it's impossible to drop features later on.
- To keep the implementation simple 3.1 / 2.7 will ship with a Python-only version of the class. It can still be rewritten in C if it turns out to be too slow or thread safety is required.
The corresponding issue in the tracker: http://bugs.python.org/issue5397 Link to the PEP: http://www.python.org/dev/peps/pep-0372/
Anything else that should be done?
Guido, I'm recommending this PEP for acceptance. Raymond
Raymond Hettinger <python <at> rcn.com> writes:
Guido, I'm recommending this PEP for acceptance.
Given you were bitten by it in your own unit tests (the "eval(repr()) does not maintain ordering" problem pointed by Georg), I think it would be better to reconsider the current __eq__ behaviour, and make it ordering-aware. Regards Antoine.
[Antoine Pitrou]
Given you were bitten by it in your own unit tests (the "eval(repr()) does not maintain ordering" problem pointed by Georg),
Completely unrelated. The original test passed because the arbitrarily ordered data in the regular dict happened to match the order added in a regular dict because I didn't shuffle the keys. There was no direct dict-to-ordered dictcomparison. Had the __eq__ method been defined differently, the test still would have passed (had a false positive).
I think it would be better to reconsider the current __eq__ behaviour, and make it ordering-aware.
If someone wants to explicitly ask for an order-sensitive comparison, the docs give a clear, simple example of how to do that. Otherwise, it's best to leave regular dict equality in-place because OrderedDicts need to be substitutable anywhere dicts are used and some of those places may make the assumption that order insensitive compares are being used. Also, the PEP outlines another issue with trying to make comparisons order sensitive. It leads to weirdness with ordereddict-to-dict comparisons making a behavior shift based on the type of one of the two inputs. It's just asking for problems and it introduces an unnecessary difference from regular dicts. Given that either choice will be surprising to someone, we opted for the simplest API with the fewest special cases and made sure the choice was clearly noted in the docs. Raymond
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Raymond, +1 on adding this to the stdlib. I especially like the idea of being able to use an ordered dict in a class's namespace. I might be able use something like that to make my enum package simpler (which currently requires assignment of the name to the integer sort order). I wanted to point out that the email package uses an ordered dictionary in its Message implementation. Messages present a dictionary-like API for its headers. I don't think I'd be able to use odicts though for this because of other semantic differences, e.g. multiple keys are allowed (though only visible through the non-mapping interface) and KeyError is never raised (like a defaultdict with a __missing__() returning None). Note though that Message's odict-like implementation is about as horribly gross as it can be: it's just a list with linear searching for key lookup. Messages should not have a billion headers. ;) Have you or Armin considered the possibility of wanting both the defaultdict and odict behavior in, say a mixin subclass? Barry -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (Darwin) iQCVAwUBSawRPXEjvBPtnXfVAQIunwQAlty1Gk3EByWK1fwOaN7+X/eC4QN4YpJL MxWy5l/So3zUM/ofu32kLEjnBLmZOZFp28ExP5QTgse6c0VzNIGP9s6JrZeeAZ7s uYk+EPChLw2GWuFgLQERpHnX9MA3XpCMbv+SheuqBROs31I7L/TCbDISk3+nOjtA LngNgWVlKW4= =glyD -----END PGP SIGNATURE-----
Raymond Hettinger <python <at> rcn.com> writes:
Completely unrelated. The original test passed because the arbitrarily ordered data in the regular dict happened to match the order added in a regular dict because I didn't shuffle the keys.
Well, I may be mistaken, but it seems your test_copying (in od5.diff) still fails to check that ordering is preserved after a copy. Unless it's not part of the contract, but then the datatype would really be ill-designed IMO.
If someone wants to explicitly ask for an order-sensitive comparison, the docs give a clear, simple example of how to do that.
That's not the point. The point is that it's not enabled by default, which is rather awkward since the whole point of the OrderedDict is that it is ordering-sensitive. Right now, equality of ordering-sensitive datatypes (e.g. list) is ordering-sensitive by default. And equality of ordering-insensitive datatypes (e.g. set) is ordering-insensitive by default.
Otherwise, it's best to leave regular dict equality in-place because OrderedDicts need to be substitutable anywhere dicts are used and some of those places may make the assumption that order insensitive compares are being used.
You seem to imply that it is more important for __eq__ to work intuitively between a non-OrderedDict and an OrderedDict, than it is to work intuitively between two OrderedDicts. It doesn't look like a common principle in Python. Witness:
list(range(3)) == set(range(3)) False list(range(3)) == tuple(range(3)) False 1 == Decimal(1) True 1 == 1.0 True 1.0 == Decimal(1) False
IMO, comparison between different types should be "best effort", and not at the price of making comparison between values of the same type less intuitive.
It's just asking for problems and it introduces an unnecessary difference from regular dicts.
What you call an "unnecessary difference" seems to be the whole motivation for introducing OrderedDicts. I see no point in trying to mitigate that difference if the new type is to be genuinely useful.
Given that either choice will be surprising to someone, we opted for the simplest API with the fewest special cases
But the current __eq__ does look like a special case, given the intended semantics of the new datatype. Not having a special case would imply having an ordering-sensitive comparison. Regards Antoine.
[Antoine Pitrou]
You seem to imply that it is more important for __eq__ to work intuitively between a non-OrderedDict and an OrderedDict, than it is to work intuitively between two OrderedDicts.
Yes. When Armin and I worked through this, it became clear that he had multiple use cases where ordered dicts needed to be used in places that had been originally designed to expect regular dicts. That was also the reason for subclassing dict. Otherwise, we would have just made a standalone class that defined all the mapping methods. I don't think we going to convince you and that's okay. We don't have to agree on every design decision. There were some reasons for either approach and we picked the one that best fit Armin's use cases, that was simplest, that introduced the fewest special rules, and did not create a Liskov violation. The choice was clearly documented and an alternative was provided for people that needed it. Outside of your differing judgment on the __eq__ method, are you basically happy with the ordered dict PEP? Raymond
On Mon, Mar 2, 2009 at 9:39 AM, Raymond Hettinger <python@rcn.com> wrote:
[Antoine Pitrou]
You seem to imply that it is more important for __eq__ to work intuitively between a non-OrderedDict and an OrderedDict, than it is to work intuitively between two OrderedDicts.
Yes. When Armin and I worked through this, it became clear that he had multiple use cases where ordered dicts needed to be used in places that had been originally designed to expect regular dicts. That was also the reason for subclassing dict. Otherwise, we would have just made a standalone class that defined all the mapping methods.
I don't think we going to convince you and that's okay. We don't have to agree on every design decision. There were some reasons for either approach and we picked the one that best fit Armin's use cases, that was simplest, that introduced the fewest special rules, and did not create a Liskov violation. The choice was clearly documented and an alternative was provided for people that needed it.
But you'll have to convince me, and so far I agree with Antoine that doing the comparison without taking the order into account feels really weird. I also think that comparing an odict to a dict with the same items and expecting them to be the same feels wrong. It is not needed to invoke Liskov: Liskov cares about the signature, not about the computed value. There is no rule that says you are not allowed to override odict.__eq__ so that it returns False in cases where Mapping.__eq__ returns True. I would propose the following formal specification for odict.__eq__: def __eq__(self, other): if not isinstance(other, odict): return NotImplemented # Give other a chance; defaults to False return list(self.items()) == list(other.items()) Obviously an actual implementation can do something more complex instead of the last line, like: for a, b in zip(self.items(), other.items()): if a != b: return False return True
Outside of your differing judgment on the __eq__ method, are you basically happy with the ordered dict PEP?
I am. -- --Guido van Rossum (home page: http://www.python.org/~guido/)
But you'll have to convince me,
Okay, here's one stab at it. If it doesn't take, I give in. ISTM, either way is right depending on your point of view and what you're trying do at the time. My judgment tips in favor of not specializing the __eq__ method. But it is not lost on me why one might think that something that iterates in a specified order would also make an order sensitive comparison.
Liskov cares about the signature, not about the computed value.
That wasn't my understanding. I thought it was entirely about computed values, "Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T." Or phrased differently, "In class hierarchies, it should be possible to treat a specialized object as if it were a base class object." In this case, Armin wants to be able to pass in an ordered dictionary to functions that weren't designed with ordered dicts in mind (config parser, json/yaml parsers, nose, unittest, etc.). Those functions should be able to assume that all the usual dictionary properties are still true. In particular, those functions may make internal comparisons to a regular dict (perhaps as a cached value) and would expect those comparisons to succeed.
I would propose the following formal specification for odict.__eq__: def __eq__(self, other): if not isinstance(other, odict): return NotImplemented # Give other a chance; defaults to False return list(self.items()) == list(other.items())
If I haven't convinced you, then I would be happy to put this in.
Outside of your differing judgment on the __eq__ method, are you basically happy with the ordered dict PEP?
I am.
Once you've decided on __eq__, can I mark the PEP as approved? Raymond
On Mon, Mar 2, 2009 at 11:20 AM, Raymond Hettinger <python@rcn.com> wrote:
But you'll have to convince me,
Okay, here's one stab at it. If it doesn't take, I give in. ISTM, either way is right depending on your point of view and what you're trying do at the time. My judgment tips in favor of not specializing the __eq__ method.
Comparing dicts is relatively uncommon. So we'd have to find and look at use cases to decide.
But it is not lost on me why one might think that something that iterates in a specified order would also make an order sensitive comparison.
My hunch is that not taking the ordering into account is going to confuse people who consciously use odicts and bother to compare them. I expect this is going to be a FAQ, no matter how much you try to document it -- especially since the concept of an odict is so simple and the API so clean that most people will not bother reading *any* docs. I expect this to be the most common use case. Use cases where people compare mappings knowing they may have different concrete types are probably exceedingly rare, and if I was doing that I wouldn't rely on __eq__ not being overridden -- IOW I'd either explicitly invoke Mapping.__eq__(a, b) or write the equivalent code myself. The third class of use case is people comparing dicts not thinking much about the possibility of there being a subclass that overrides __eq__, and being surprised by the substitution of an odict. This seems to be the use case you favor; to me it seems pretty rare too. To convince me otherwise you'd have to find a common use case that does this *and* is likely to encounter an odict in real life.
Liskov cares about the signature, not about the computed value.
That wasn't my understanding. I thought it was entirely about computed values, "Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T." Or phrased differently, "In class hierarchies, it should be possible to treat a specialized object as if it were a base class object."
This strict interpretation is violated all the time in OO programming; consider e.g. the common overriding of object.__repr__. (In fact, even the definition of dict.__eq__ overriding object.__eq__ would validate it.) AFAIK a more common use of the term in OO languages is about signatures only: if a method of class C accepts an argument of type T, then you shouldn't override that method in a class D derived from C to require an argument type S which is a subtype of T. (This is also known as Contravariance. Read the section on Design by contract in http://en.wikipedia.org/wiki/Liskov_substitution_principle.)
In this case, Armin wants to be able to pass in an ordered dictionary to functions that weren't designed with ordered dicts in mind (config parser, json/yaml parsers, nose, unittest, etc.). Those functions should be able to assume that all the usual dictionary properties are still true. In particular, those functions may make internal comparisons to a regular dict (perhaps as a cached value) and would expect those comparisons to succeed.
That's a hypothetical use case. Have you found any real code that uses __eq__ on dicts in this matter?
I would propose the following formal specification for odict.__eq__:
def __eq__(self, other): if not isinstance(other, odict): return NotImplemented # Give other a chance; defaults to False return list(self.items()) == list(other.items())
If I haven't convinced you, then I would be happy to put this in.
Great.
Outside of your differing judgment on the __eq__ method, are you basically happy with the ordered dict PEP?
I am.
Once you've decided on __eq__, can I mark the PEP as approved?
Yes. (With the caveat that I haven't read it very closely, but the basic spec seems sound apart from the __eq__ issue.) Hm, I wonder if you should spec odict.__repr__ (and hence odict.__str__). It would be confusing if an odict's repr() were the same as a plain dict's. -- --Guido van Rossum (home page: http://www.python.org/~guido/)
This strict interpretation is violated all the time in OO programming; consider e.g. the common overriding of object.__repr__. (In fact, even the definition of dict.__eq__ overriding object.__eq__ would validate it.) AFAIK a more common use of the term in OO languages is about signatures only:
Slightly off-topic: I think what matters in reality is a difficult-to-formulate *specification* of the behavior of the operation also. I.e. not /all/ provable properties of the base implementation need to be maintained, but only those occurring in the specification of the base operation. Applications using the base then can only rely on the *specified* properties of the operations they use, and there you get substitutability. Of course, what properties are part of the specification is an ongoing discussion for many class hierarchies, in many languages (see e.g. the relationship between __eq__ and __hash__). Beyond transitivity and consistency with __hash__ (which is irrelevant here), I don't think odict.__eq__ should be restricted to behave the same as dict.__eq__. Regards, Martin
[Me]
In this case, Armin wants to be able to pass in an ordered dictionary to functions that weren't designed with ordered dicts in mind (config parser, json/yaml parsers, nose, unittest, etc.). Those functions should be able to assume that all the usual dictionary properties are still true. In particular, those functions may make internal comparisons to a regular dict (perhaps as a cached value) and would expect those comparisons to succeed.
One other thought: I was intending to modify namedtuple's _asdict() method to return an OrderedDict but don't want to break any existing code that relies on the returned object having an order insensitive comparison. A object that currently returns a dict should be able to return an OrderedDict without breaking anything. The proposed change precludes this possibility as well as the ones mentioned above. Raymond
On Mon, Mar 2, 2009 at 11:47 AM, Raymond Hettinger <python@rcn.com> wrote:
[Me]
In this case, Armin wants to be able to pass in an ordered dictionary to functions that weren't designed with ordered dicts in mind (config parser, json/yaml parsers, nose, unittest, etc.). Those functions should be able to assume that all the usual dictionary properties are still true. In particular, those functions may make internal comparisons to a regular dict (perhaps as a cached value) and would expect those comparisons to succeed.
One other thought: I was intending to modify namedtuple's _asdict() method to return an OrderedDict but don't want to break any existing code that relies on the returned object having an order insensitive comparison.
But do you know if any code that relies on that? Have you ever written any yourself? If you really worry about this so much you could not make this change, or you'd have to return a custom subclass of odict that overrides __eq__ again.
A object that currently returns a dict should be able to return an OrderedDict without breaking anything. The proposed change precludes this possibility as well as the ones mentioned above.
Well, such are the joys of strict backwards compatibility. If something works fine with a dict today, there's no strong need to return an odict tomorrow. You could always add a new API that returns an odict. -- --Guido van Rossum (home page: http://www.python.org/~guido/)
Compromise? def __eq__(self, other): if isinstance(other, OrderedDict): return all(map(operator.eq, self.items(), other.items())) if isinstance(other, Mapping): return dict.__eq__(self, other) return NotImplemented # Give other a chance; defaults to False OrderedDict-to-OrderedDict comparisons are order sensitive -- matching your intuition OrderedDict-to-OtherMappings -- allow me and Armin to have our substitutability for dicts. Raymond
On Mon, Mar 2, 2009 at 12:07 PM, Raymond Hettinger <python@rcn.com> wrote:
Compromise?
def __eq__(self, other): if isinstance(other, OrderedDict): return all(map(operator.eq, self.items(), other.items())) if isinstance(other, Mapping): return dict.__eq__(self, other) return NotImplemented # Give other a chance; defaults to False
OrderedDict-to-OrderedDict comparisons are order sensitive -- matching your intuition OrderedDict-to-OtherMappings -- allow me and Armin to have our substitutability for dicts.
This sounds fair. Note that dict.__eq__ actually returns NotImplemented if not isinstance(other, dict) so you could tighten the test to isinstance(other, dict) if you wanted to. -- --Guido van Rossum (home page: http://www.python.org/~guido/)
[GvR]
This sounds fair. Note that dict.__eq__ actually returns NotImplemented if not isinstance(other, dict) so you could tighten the test to isinstance(other, dict) if you wanted to.
Okay. Done deal. Raymond
Hi, Guido van Rossum <guido <at> python.org> writes:
This sounds fair. Note that dict.__eq__ actually returns NotImplemented if not isinstance(other, dict) so you could tighten the test to isinstance(other, dict) if you wanted to. I'm actually very happy with that decision. The original PEP was doing exactly that and I still think it makes more sense.
[sorry Raymond :)] Regards, Armin
2009/3/1 Armin Ronacher <armin.ronacher@active-4.com>:
Hi everybody,
PEP 372 was modified so that it provides a simpler API (only the dict API to be exact) and it was decided to start with a Python-only implementation and replace it with a C version later if necessary.
Annotated changes from earlier versions of the PEP:
- the extra API for ordered dict was dropped to keep the interface simple and clean. Future versions can still be expanded but it's impossible to drop features later on.
- To keep the implementation simple 3.1 / 2.7 will ship with a Python-only version of the class. It can still be rewritten in C if it turns out to be too slow or thread safety is required.
The corresponding issue in the tracker: http://bugs.python.org/issue5397 Link to the PEP: http://www.python.org/dev/peps/pep-0372/
Anything else that should be done?
Have you considered naming? I would think that "odict" or "ordereddict" would be more consistent with other collections names especially "defaultdict". -- Regards, Benjamin
Benjamin Peterson schrieb:
2009/3/1 Armin Ronacher <armin.ronacher@active-4.com>:
Hi everybody,
PEP 372 was modified so that it provides a simpler API (only the dict API to be exact) and it was decided to start with a Python-only implementation and replace it with a C version later if necessary.
Annotated changes from earlier versions of the PEP:
- the extra API for ordered dict was dropped to keep the interface simple and clean. Future versions can still be expanded but it's impossible to drop features later on.
- To keep the implementation simple 3.1 / 2.7 will ship with a Python-only version of the class. It can still be rewritten in C if it turns out to be too slow or thread safety is required.
The corresponding issue in the tracker: http://bugs.python.org/issue5397 Link to the PEP: http://www.python.org/dev/peps/pep-0372/
Anything else that should be done?
Have you considered naming? I would think that "odict" or "ordereddict" would be more consistent with other collections names especially "defaultdict".
We're already quite inconsistent with type name casing in the collections module, so it wouldn't matter so much. (Though I'd find symmetry with defaultdict pleasing as well.) Georg
On 02/03/2009 22:28, Georg Brandl wrote:
We're already quite inconsistent with type name casing in the collections module, so it wouldn't matter so much. (Though I'd find symmetry with defaultdict pleasing as well.)
Since the odict naming is already so prevalent in the wild, it seems to me like that would be the best candidate. (Plus, it's shorter!) /bikeshedding Cheers, Dirkjan
Raymond Hettinger wrote:
/bikeshedding
Yes. Also we need to paint it green with pink polka dots :-)
Or should that be pink with green polka dots? ;) Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------
On Mon, Mar 2, 2009 at 1:28 PM, Georg Brandl <g.brandl@gmx.net> wrote:
Benjamin Peterson schrieb:
2009/3/1 Armin Ronacher <armin.ronacher@active-4.com>:
Hi everybody,
PEP 372 was modified so that it provides a simpler API (only the dict API to be exact) and it was decided to start with a Python-only implementation and replace it with a C version later if necessary.
Annotated changes from earlier versions of the PEP:
- the extra API for ordered dict was dropped to keep the interface simple and clean. Future versions can still be expanded but it's impossible to drop features later on.
- To keep the implementation simple 3.1 / 2.7 will ship with a Python-only version of the class. It can still be rewritten in C if it turns out to be too slow or thread safety is required.
The corresponding issue in the tracker: http://bugs.python.org/issue5397 Link to the PEP: http://www.python.org/dev/peps/pep-0372/
Anything else that should be done?
Have you considered naming? I would think that "odict" or "ordereddict" would be more consistent with other collections names especially "defaultdict".
We're already quite inconsistent with type name casing in the collections module, so it wouldn't matter so much. (Though I'd find symmetry with defaultdict pleasing as well.)
+1 for odict. Somehow I thought that was the name proposed by the PEP. :-( -- --Guido van Rossum (home page: http://www.python.org/~guido/)
+1 for odict. Somehow I thought that was the name proposed by the PEP. It originally was, Raymond wanted to change it. I would still vote for odict if
Guido van Rossum <guido <at> python.org> writes: that's still possible :) Regards, Armin
Guido van Rossum wrote:
+1 for odict. Somehow I thought that was the name proposed by the PEP. :-(
The examples in the PEP used 'odict' (until recently), but the patch was for OrderedDict. I don't personally mind either way. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------
[Nick Coghlan]
The examples in the PEP used 'odict' (until recently), but the patch was for OrderedDict.
As an experiment, try walking down the hall asking a few programmers who aren't in this conversion what they think collections.odict() is? Is it a class or function? What does it do? Can the English as second language folks guess what the o stands for? Is it a builtin or pure python? My guess is that the experiment will be informative. When we use the class, we typically only spell-out the constructor once while actually using the returned object many times. So, have we really saved any typing? In the context of other applications, which is clearer? json.loads(jtext, object_pairs_hook=odict) config = ConfigParser(dict_type=odict) or json.loads(jtext, object_pairs_hook=OrderedDict) config = ConfigParser(dict_type=OrderedDict) I find the former to be non-communicative. Raymond
Raymond Hettinger <python <at> rcn.com> writes:
[Nick Coghlan]
The examples in the PEP used 'odict' (until recently), but the patch was for OrderedDict.
As an experiment, try walking down the hall asking a few programmers who
aren't in this conversion what they
think collections.odict() is?
I second that odict is too terse, and it's also a recipe for subtle typos. I think that both ordereddict and OrderedDict can't go wrong. Regards Antoine.
Is it a class or function? What does it do? Can the English as second language folks guess what the o stands for? Is it a builtin or pure python? My guess is that the experiment will be informative.
I'll do that tomorrow (if I manage to remember). My guess is that "ordered dictionary" is as descriptive to them as "odict" or "blonzo" (well, perhaps they do recognize the "dictionary" part of it, and manage not to confuse it with "directory"). As for the "ordered" part, my guess is that most people will suggest that it means "sorted" (native speakers or not). Regards, Martin
Hi, Raymond Hettinger <python <at> rcn.com> writes:
When we use the class, we typically only spell-out the constructor once while actually using the returned object many times. So, have we really saved any typing? I'm fine with the typed out name as well, but I still would prefer lowercase to stay consistent with defaultdict/dict.
Unfortunately PEP 8 never really took off naming-wise, so we're mostly following the "reuse the naming scheme from existing code in the same module" rule, and I think there lowercase wins, thanks to defaultdict. Regards, Armin
2009/3/2 Armin Ronacher <armin.ronacher@active-4.com>:
Hi,
Raymond Hettinger <python <at> rcn.com> writes:
When we use the class, we typically only spell-out the constructor once while actually using the returned object many times. So, have we really saved any typing? I'm fine with the typed out name as well, but I still would prefer lowercase to stay consistent with defaultdict/dict.
+1 -- Regards, Benjamin
Unfortunately PEP 8 never really took off naming-wise, so we're mostly following the "reuse the naming scheme from existing code in the same module" rule, and I think there lowercase wins, thanks to defaultdict.
Traditionally, the all lowercase name referred to a C type. The other classes in collections are named Counter, UserDict, UserList, UserString, MutableMapping, etc. Besides, the lowercase/uppercase distinction helps us distinguish functions from classes. This is the way I've see every Python book do it since the dawn of time. Raymond
On Mon, Mar 2, 2009 at 3:13 PM, Raymond Hettinger <python@rcn.com> wrote:
Unfortunately PEP 8 never really took off naming-wise, so we're mostly following the "reuse the naming scheme from existing code in the same module" rule, and I think there lowercase wins, thanks to defaultdict.
Traditionally, the all lowercase name referred to a C type. The other classes in collections are named Counter, UserDict, UserList, UserString, MutableMapping, etc. Besides, the lowercase/uppercase distinction helps us distinguish functions from classes. This is the way I've see every Python book do it since the dawn of time.
Then they're all wrong. In 3.0 we're moving away from this, e.g. cPickle is gone, so is cStringIO. The implementation language should not shine through. *Maybe* the "built-in status" should guide the capitalization, so only built-in types are lowercase (str, int, dict etc.). Anyway, it seems the collections module in particular is already internally inconsistent -- NamedTuple vs. defaultdict. In a sense defaultdict is the odd one out here, since these are things you import from some module, they're not built-in. Maybe it should be renamed to NamedDict? -- --Guido van Rossum (home page: http://www.python.org/~guido/)
[GvR]
*Maybe* the "built-in status" should guide the capitalization, so only built-in types are lowercase (str, int, dict etc.).
That makes sense.
Anyway, it seems the collections module in particular is already internally inconsistent -- NamedTuple vs. defaultdict.
FWIW, namedtuple() is a factory function that creates a class, it isn't a class itself. There are no instances of namedtuple(). Most functions are all lowercase. Don't know if that applies to factory functions too. Raymond
On Mon, Mar 2, 2009 at 3:43 PM, Raymond Hettinger <python@rcn.com> wrote:
[GvR]
*Maybe* the "built-in status" should guide the capitalization, so only built-in types are lowercase (str, int, dict etc.).
That makes sense.
Anyway, it seems the collections module in particular is already internally inconsistent -- NamedTuple vs. defaultdict.
FWIW, namedtuple() is a factory function that creates a class, it isn't a class itself. There are no instances of namedtuple(). Most functions are all lowercase. Don't know if that applies to factory functions too.
This is unfortunately ambiguous; e.g. threading.Lock() is a factory function too. Anyways, I was mistaken about this example; I should have pointed to Counter and the UserXxx classes in collections.py. On Mon, Mar 2, 2009 at 3:44 PM, Armin Ronacher <armin.ronacher@active-
I suppose you mean "DefaultDict".
Yes, I've been distracted. :-(
That would actually be the best solution. Then the module would be consistent and the new ordered dict version would go by the name "OrderedDict".
OK.
PS.: so is datetime.datetime a builtin then? :)
Another historic accident. Like socket.socket. :-( -- --Guido van Rossum (home page: http://www.python.org/~guido/)
Guido van Rossum wrote:
On Mon, Mar 2, 2009 at 3:43 PM, Raymond Hettinger <python@rcn.com> wrote:
[GvR]
*Maybe* the "built-in status" should guide the capitalization, so only built-in types are lowercase (str, int, dict etc.). That makes sense.
Anyway, it seems the collections module in particular is already internally inconsistent -- NamedTuple vs. defaultdict. FWIW, namedtuple() is a factory function that creates a class, it isn't a class itself. There are no instances of namedtuple(). Most functions are all lowercase. Don't know if that applies to factory functions too.
This is unfortunately ambiguous; e.g. threading.Lock() is a factory function too. Anyways, I was mistaken about this example; I should have pointed to Counter and the UserXxx classes in collections.py.
On Mon, Mar 2, 2009 at 3:44 PM, Armin Ronacher <armin.ronacher@active-
I suppose you mean "DefaultDict".
Yes, I've been distracted. :-(
That would actually be the best solution. Then the module would be consistent and the new ordered dict version would go by the name "OrderedDict".
OK.
PS.: so is datetime.datetime a builtin then? :)
Another historic accident. Like socket.socket. :-(
A pity this stuff wasn't addressed for 3.0. Way too late now, though. regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/
On Mar 2, 2009, at 7:08 PM, Steve Holden wrote:
PS.: so is datetime.datetime a builtin then? :)
Another historic accident. Like socket.socket. :-(
A pity this stuff wasn't addressed for 3.0. Way too late now, though.
It may be too late to rename the existing accidents, but why not add consistently-named aliases (socket.Socket, datetime.DateTime, etc) and strongly encourage their use in new code? -- Ivan Krstić <krstic@solarsail.hcs.harvard.edu> | http://radian.org
On Tue, 3 Mar 2009 at 06:01, Ivan Krsti�~G wrote:
On Mar 2, 2009, at 7:08 PM, Steve Holden wrote:
PS.: so is datetime.datetime a builtin then? :)
Another historic accident. Like socket.socket. :-(
A pity this stuff wasn't addressed for 3.0. Way too late now, though.
It may be too late to rename the existing accidents, but why not add consistently-named aliases (socket.Socket, datetime.DateTime, etc) and strongly encourage their use in new code?
As a user I'd be +1 on that. In fact, I might even start using 'as' in my own code for that purpose right now. I've always felt vaguely confused and disturbed whenever I imported 'datetime', but until this discussion I didn't realize why :) Thinking about it, I know I've written 'from datetime import DateTime' a number of times and then had to go back and fix my code when I tried to run it. And I'm sure that sometimes when that happens I've had to (re)read the docs (or do a 'dir') to find out why my import wasn't working. Having said all that out loud, I think I might be stronger than a +1 on this idea. I'd be willing to help with doc and even code patches once I finish learning how to contribute properly. --RDM
On Tue, Mar 3, 2009 at 05:13, <rdmurray@bitdance.com> wrote:
On Tue, 3 Mar 2009 at 06:01, Ivan KrstiÄ~G wrote:
On Mar 2, 2009, at 7:08 PM, Steve Holden wrote:
PS.: so is datetime.datetime a builtin then? :) Another historic accident. Like socket.socket. :-(
A pity this stuff wasn't addressed for 3.0. Way too late now, though.
It may be too late to rename the existing accidents, but why not add consistently-named aliases (socket.Socket, datetime.DateTime, etc) and strongly encourage their use in new code?
Or make the old names aliases for the new names and start a PendingDeprecationWarning on the old names so they can be switched in the distant future?
As a user I'd be +1 on that. In fact, I might even start using 'as' in my own code for that purpose right now. I've always felt vaguely confused and disturbed whenever I imported 'datetime', but until this discussion I didn't realize why :) Thinking about it, I know I've written 'from datetime import DateTime' a number of times and then had to go back and fix my code when I tried to run it. And I'm sure that sometimes when that happens I've had to (re)read the docs (or do a 'dir') to find out why my import wasn't working.
Having said all that out loud, I think I might be stronger than a +1 on this idea. I'd be willing to help with doc and even code patches once I finish learning how to contribute properly.
+1 from me to fix these little mishaps in naming in both modules. -Brett
On Tue, Mar 3, 2009 at 5:15 PM, Brett Cannon <brett@python.org> wrote:
On Tue, Mar 3, 2009 at 05:13, <rdmurray@bitdance.com> wrote:
On Tue, 3 Mar 2009 at 06:01, Ivan KrstiÄ~G wrote:
On Mar 2, 2009, at 7:08 PM, Steve Holden wrote:
PS.: so is datetime.datetime a builtin then? :) Another historic accident. Like socket.socket. :-(
A pity this stuff wasn't addressed for 3.0. Way too late now, though.
A pity indeed.
It may be too late to rename the existing accidents, but why not add consistently-named aliases (socket.Socket, datetime.DateTime, etc) and strongly encourage their use in new code?
Or make the old names aliases for the new names and start a PendingDeprecationWarning on the old names so they can be switched in the distant future?
+1, if it's not done in a rush and only for high-visibility modules -- let's start with socket and datetime. We need a really long lead time before we can remove these. I recommend starting with a *silent* deprecation in 3.1 combined with a PR offensive for the new names.
As a user I'd be +1 on that. In fact, I might even start using 'as' in my own code for that purpose right now. I've always felt vaguely confused and disturbed whenever I imported 'datetime', but until this discussion I didn't realize why :) Thinking about it, I know I've written 'from datetime import DateTime' a number of times and then had to go back and fix my code when I tried to run it. And I'm sure that sometimes when that happens I've had to (re)read the docs (or do a 'dir') to find out why my import wasn't working.
Having said all that out loud, I think I might be stronger than a +1 on this idea. I'd be willing to help with doc and even code patches once I finish learning how to contribute properly.
+1 from me to fix these little mishaps in naming in both modules.
-- --Guido van Rossum (home page: http://www.python.org/~guido/)
It may be too late to rename the existing accidents, but why not add consistently-named aliases (socket.Socket, datetime.DateTime, etc) and strongly encourage their use in new code?
Or make the old names aliases for the new names and start a PendingDeprecationWarning on the old names so they can be switched in the distant future?
Should the names in the __repr__ be changed now or later? >>> datetime(2008, 7, 31, 12, 0, 0) datetime.datetime(2008, 7, 31, 12, 0) Raymond
We need a really long lead time before we can remove these. I recommend starting with a *silent* deprecation in 3.1 combined with a PR offensive for the new names.
I think the old names basically have to live forever in some way, due to loading old pickles. Remember the problems we had when we tried to restructure the library in 2.6?
On Tue, Mar 3, 2009 at 17:30, Eric Smith <eric@trueblade.com> wrote:
We need a really long lead time before we can remove these. I
recommend starting with a *silent* deprecation in 3.1 combined with a PR offensive for the new names.
I think the old names basically have to live forever in some way, due to loading old pickles. Remember the problems we had when we tried to restructure the library in 2.6?
Forever is a long time. =) If we keep the PendingDeprecationWarning for a long time and really get the word out of the renames then people can migrate their pickles over time. The real problem with the 2.6 reorg was that people didn't want to have zero lead time to update their pickles and they way the transition was being handled. In this case the old names and simply subclass the new names and have no issues with old code. -Brett
Brett Cannon wrote:
On Tue, Mar 3, 2009 at 17:30, Eric Smith <eric@trueblade.com <mailto:eric@trueblade.com>> wrote:
We need a really long lead time before we can remove these. I recommend starting with a *silent* deprecation in 3.1 combined with a PR offensive for the new names.
I think the old names basically have to live forever in some way, due to loading old pickles. Remember the problems we had when we tried to restructure the library in 2.6?
Forever is a long time. =) If we keep the PendingDeprecationWarning for a long time and really get the word out of the renames then people can migrate their pickles over time. The real problem with the 2.6 reorg was that people didn't want to have zero lead time to update their pickles and they way the transition was being handled. In this case the old names and simply subclass the new names and have no issues with old code.
There's also no reason why someone couldn't write a pickle updater for when such problems do rear their ugly heads. regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/
2009/3/3 Brett Cannon <brett@python.org>:
On Tue, Mar 3, 2009 at 17:30, Eric Smith <eric@trueblade.com> wrote:
We need a really long lead time before we can remove these. I recommend starting with a *silent* deprecation in 3.1 combined with a PR offensive for the new names.
I think the old names basically have to live forever in some way, due to loading old pickles. Remember the problems we had when we tried to restructure the library in 2.6?
Forever is a long time. =) If we keep the PendingDeprecationWarning for a long time and really get the word out of the renames then people can migrate their pickles over time. The real problem with the 2.6 reorg was that people didn't want to have zero lead time to update their pickles and they way the transition was being handled. In this case the old names and simply subclass the new names and have no issues with old code.
Yes, I'm already looking forward to Py4k now. :) -- Regards, Benjamin
Benjamin Peterson wrote:
Yes, I'm already looking forward to Py4k now. :)
Shh, Guido will need at least 5 years before he's ready to contemplate going through something like this again. Or maybe a decade to be on the safe side ;) Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------
On Wed, Mar 4, 2009 at 3:23 AM, Nick Coghlan <ncoghlan@gmail.com> wrote:
Benjamin Peterson wrote:
Yes, I'm already looking forward to Py4k now. :)
Shh, Guido will need at least 5 years before he's ready to contemplate going through something like this again.
Or maybe a decade to be on the safe side ;)
Actually Py4k will have to be on the next BDFL's watch. :) -- --Guido van Rossum (home page: http://www.python.org/~guido/)
2009/3/4 Guido van Rossum <guido@python.org>:
On Wed, Mar 4, 2009 at 3:23 AM, Nick Coghlan <ncoghlan@gmail.com> wrote:
Benjamin Peterson wrote:
Yes, I'm already looking forward to Py4k now. :)
Shh, Guido will need at least 5 years before he's ready to contemplate going through something like this again.
Or maybe a decade to be on the safe side ;)
Actually Py4k will have to be on the next BDFL's watch. :)
Somebody warn Orlijn now!!! :-) Paul.
Anyway, it seems the collections module in particular is already internally inconsistent -- NamedTuple vs. defaultdict. In a sense defaultdict is the odd one out here, since these are things you import from some module, they're not built-in. Maybe it should be renamed to NamedDict? I suppose you mean "DefaultDict". That would actually be the best solution. Then the module would be consistent and the new ordered dict version would go by
Hi, Guido van Rossum <guido <at> python.org> writes: the name "OrderedDict". Regards, Armin PS.: so is datetime.datetime a builtin then? :)
Quick question? Is PEP 8 still current for what is being done in Py3.x? I just took a quick look and it says: Class Names Almost without exception, class names use the CapWords convention. Classes for internal use have a leading underscore in addition. ----- Original Message ----- From: "Guido van Rossum" <guido@python.org> To: "Raymond Hettinger" <python@rcn.com> Cc: <python-dev@python.org>; "Armin Ronacher" <armin.ronacher@active-4.com> Sent: Monday, March 02, 2009 3:38 PM Subject: Re: [Python-Dev] PEP 372 -- Adding an ordered directory to collections ready for pronouncement On Mon, Mar 2, 2009 at 3:13 PM, Raymond Hettinger <python@rcn.com> wrote:
Unfortunately PEP 8 never really took off naming-wise, so we're mostly following the "reuse the naming scheme from existing code in the same module" rule, and I think there lowercase wins, thanks to defaultdict.
Traditionally, the all lowercase name referred to a C type. The other classes in collections are named Counter, UserDict, UserList, UserString, MutableMapping, etc. Besides, the lowercase/uppercase distinction helps us distinguish functions from classes. This is the way I've see every Python book do it since the dawn of time.
Then they're all wrong. In 3.0 we're moving away from this, e.g. cPickle is gone, so is cStringIO. The implementation language should not shine through. *Maybe* the "built-in status" should guide the capitalization, so only built-in types are lowercase (str, int, dict etc.). Anyway, it seems the collections module in particular is already internally inconsistent -- NamedTuple vs. defaultdict. In a sense defaultdict is the odd one out here, since these are things you import from some module, they're not built-in. Maybe it should be renamed to NamedDict? -- --Guido van Rossum (home page: http://www.python.org/~guido/)
On Mon, Mar 2, 2009 at 3:52 PM, Raymond Hettinger <python@rcn.com> wrote:
Quick question? Is PEP 8 still current for what is being done in Py3.x? I just took a quick look and it says:
Class Names
Almost without exception, class names use the CapWords convention. Classes for internal use have a leading underscore in addition.
Yes, this is still the rule for new classes. I am *not* (have never been) in favor of a hasty overhaul of established APIs. Some of these were fixed for 3.0 (e.g. cPickle). The rest will just be deviant forever. Not a big deal as long as the number is fixed and limit. -- --Guido van Rossum (home page: http://www.python.org/~guido/)
On Mon, 02 Mar 2009 14:36:32 -0800, Raymond Hettinger wrote:
[Nick Coghlan]
The examples in the PEP used 'odict' (until recently), but the patch was for OrderedDict.
As an experiment, try walking down the hall asking a few programmers who aren't in this conversion what they think collections.odict() is? Is it a class or function? What does it do? Can the English as second language folks guess what the o stands for? Is it a builtin or pure python? My guess is that the experiment will be informative.
Just today, I was talking with a colleague (which is learning Python right now) about "ordered dict". His first thought was a dictionary that, when iterated, would return keys in sorted order. I beleive he was partly misguided by his knowledge of C++. C++ has always had std::map which returns sorted data upon iteration (it's a binary tree); they're now adding std::unordered_map (and std::unordered_set), to be implemented with a hash table. So, if you come from C++, it's easy to mistake the meaning of an ordered dict. This said, I don't have a specific suggestion, but I would stay with lowercase-only for simmetry with defaultdict. -- Giovanni Bajo Develer S.r.l. http://www.develer.com
Giovanni Bajo wrote:
Just today, I was talking with a colleague (which is learning Python right now) about "ordered dict". His first thought was a dictionary that, when iterated, would return keys in sorted order.
I wonder whether "indexed list" would be a more appropriate name for what we're talking about here -- basically a sequence type that holds things in arbitrary order, but with the additional ability to look things up quickly by a key. -- Greg
Greg Ewing wrote:
Giovanni Bajo wrote:
Just today, I was talking with a colleague (which is learning Python right now) about "ordered dict". His first thought was a dictionary that, when iterated, would return keys in sorted order.
I wonder whether "indexed list" would be a more appropriate name for what we're talking about here -- basically a sequence type that holds things in arbitrary order, but with the additional ability to look things up quickly by a key.
I almost agree, except that the API uses the dict, not list, API. For instance, items are appended by adding a key, not with .append. With sort not available and .popitem removing the last added item, 'indexed stack' would be a bit closer. Indeed, I plan to try out odicts with graph algorithms that need keyed access to stacked items. tjr
Terry Reedy wrote:
I almost agree, except that the API uses the dict, not list, API.
Yes, as long as the API is dict-like, it really needs to be thought of as a kind of dict. Perhaps the terminology should be ordereddict -- what we have here sorteddict -- hypothetical future type that keeps itself sorted in key order -- Greg
On approximately 3/3/2009 4:51 PM, came the following characters from the keyboard of Greg Ewing:
Terry Reedy wrote:
I almost agree, except that the API uses the dict, not list, API.
Yes, as long as the API is dict-like, it really needs to be thought of as a kind of dict.
Perhaps the terminology should be
ordereddict -- what we have here
sorteddict -- hypothetical future type that keeps itself sorted in key order
FIFOdict ? Yeah, that blows the capitalization scheme, way, way out. The problem with the ordereddict/OrderedDict/odict is that there are way too many possible orderings, and without being more specific (InsertionSequenceOrderPreservingDictionary) people are doing to think "sort" when they hear "ordered". I think FIFOdict is a reasonable abbreviation for InsertionSequenceOrderPreservingDictionary :) -- Glenn -- http://nevcal.com/ =========================== A protocol is complete when there is nothing left to remove. -- Stuart Cheshire, Apple Computer, regarding Zero Configuration Networking
Perhaps the terminology should be
ordereddict -- what we have here
sorteddict -- hypothetical future type that keeps itself sorted in key order
+1
FIFOdict ? Yeah, that blows the capitalization scheme, way, way out.
Issues: * The popitem() method is LIFO. * In a non-popping context, there is no OUT. It just stores. * FIFO is more suggestive of queue behavior which does not apply here. * Stores to existing keys don't go at the end; they leave the order unchanged. FWIW, PEP 372 has links to seven other independent implementations and they all have names that are some variant spelling OrderedDict except for one which goes by the mysterious name of StableDict. Am still +1 on painting the class green with pink polka dots, but I'm starting to appreciate why others are insisting on pink with green polka dots ;-) Raymond
On approximately 3/3/2009 11:22 PM, came the following characters from the keyboard of Raymond Hettinger:
Perhaps the terminology should be
ordereddict -- what we have here
sorteddict -- hypothetical future type that keeps itself sorted in key order
+1
-1 Introducing the hypothetical sorteddict would serve to reduce the likelihood of ordereddict being interpreted as sorteddict among the small percentage of people that actually read the two lines that might mention it in the documentation, but wouldn't significantly aid the intuition of people who first encounter it in someone else's code. And without an implementation, it would otherwise be documentation noise, not signal.
FIFOdict ? Yeah, that blows the capitalization scheme, way, way out.
Issues: * The popitem() method is LIFO.
But traversal starts at the other end, if I understand correctly. popitem seems gratuitous (but handy and cheap)
* In a non-popping context, there is no OUT. It just stores. * FIFO is more suggestive of queue behavior which does not apply here.
It is suggestive of queue behavior, and the items are a queue if looked at from insertion, and traversal perspectives, if I understand correctly. But without OUT, FIFO is a bit too aggressively suggestively of queues... but not more so than ordereddict is a bit too suggestive of sorted behavior... And at least FIFO doesn't have the sorting connotation.
* Stores to existing keys don't go at the end; they leave the order unchanged.
FWIW, PEP 372 has links to seven other independent implementations and they all have names that are some variant spelling OrderedDict except for one which goes by the mysterious name of StableDict.
Well, just because six other independent implementations use a name with connotations that they don't live up to is no reason to perpetuate such foolishness, nor introduce it into the Python stdlib. StableDict, eh? That's not so mysterious, perhaps, if you think of stable sorts^H^H^H^H^H (whoops, there's the wrong connotation rearing its ugly head again, sorry).
Am still +1 on painting the class green with pink polka dots, but I'm starting to appreciate why others are insisting on pink with green polka dots ;-)
Sure. I didn't expect FIFOdict to be an extremely useful suggestion, but I wanted to make the point that if the name has an erroneous connotation, use a name that doesn't. And to get the discussion above flowing, to find out more about your thinking in the matter. InputOrderedDict might be more descriptive, yet not as long as that other atrocity I alluded to that you rightfully refused to quote :) From tree-walking, perhaps people would intuit the right connotations from InOrderDict which is no longer than ordereddict, but usually the tree is kept sorted too, so I'm afraid it might not be sufficient. Maybe SequenceDict ? SeqPreservingDict ? SeqDict ? All of these talk about sequences, which are generally not implied to be sorted. I like these well enough, and it is late enough, that I'm not going to think of more right now. C'mon folks, brainstorm, don't complain about ordereddict if you can't come up with some alternatives for discussion!!! (and some reasons why the suggestions might be good or bad) Even your bad ideas might trigger a good name in someone else's head... -- Glenn -- http://nevcal.com/ =========================== A protocol is complete when there is nothing left to remove. -- Stuart Cheshire, Apple Computer, regarding Zero Configuration Networking
On Mar 4, 2009, at 9:01 , Glenn Linderman wrote:
On approximately 3/3/2009 11:22 PM, came the following characters from the keyboard of Raymond Hettinger:
Perhaps the terminology should be
ordereddict -- what we have here
sorteddict -- hypothetical future type that keeps itself sorted in key order +1
-1
Introducing the hypothetical sorteddict would serve to reduce the likelihood of ordereddict being interpreted as sorteddict among the small percentage of people that actually read the two lines that might mention it in the documentation, but wouldn't significantly aid the intuition of people who first encounter it in someone else's code.
And without an implementation, it would otherwise be documentation noise, not signal.
Instead of introducing a sorteddict I would instead suggest that the future should bring an odict with a sort method; possibly also keys_sorted and items_sorted methods. I think this would simplify things and putting these methods into the odict documentation makes it clearer how it actually behaves for people that just scan the method index to get an impression of what the object is about. Regards, Gisle
Hello all, First a comment on-thread: I can't wait to get an ordered dictionary in the stdlib! The discussion regarding suggestions for the name appears to be ongoing. What about the name 'orderdict' instead of 'ordereddict'?. It doesn't contain the double-d, is slightly shorter, and I think a little more typo-friendly. Just my 2c, please feel free to ignore. OrderDict would of course be the alternative-casing version. Secondly, regarding this list: I couldn't find a lot of documentation regarding list culture, so I'm quite nervous about the potential for stepping in where I'm not welcome before I have spent a lot of time 'spinning up' on this issues of this list. I am interested in learning more about how Python is written and, if I can, providing some assistance to that task. However it's going to be a long, slow process for me. At the same time, I do have firsthand knowledge of how hard it can be to get people to contribute to anything to any degree, and as such don't want to be a part of the problem by being too tentative in introducing myself. I would appreciate any pointers regarding what is appreciated on this list and what is not. Hopefully, over time I will be able to make some form of useful, concrete code contributions in the form of patches or documentation, but I do realise it will take a lot of hands-on learning first. Trying to grok the discussions on this list seems like a big part of that. Thanks, -Tennessee
Tennessee Leeuwenburg wrote:
Hello all,
First a comment on-thread: I can't wait to get an ordered dictionary in the stdlib! The discussion regarding suggestions for the name appears to be ongoing. What about the name 'orderdict' instead of 'ordereddict'?. It doesn't contain the double-d, is slightly shorter, and I think a little more typo-friendly. Just my 2c, please feel free to ignore. OrderDict would of course be the alternative-casing version.
Secondly, regarding this list: I couldn't find a lot of documentation regarding list culture, so I'm quite nervous about the potential for stepping in where I'm not welcome before I have spent a lot of time 'spinning up' on this issues of this list. I am interested in learning more about how Python is written and, if I can, providing some assistance to that task. However it's going to be a long, slow process for me. At the same time, I do have firsthand knowledge of how hard it can be to get people to contribute to anything to any degree, and as such don't want to be a part of the problem by being too tentative in introducing myself.
I would appreciate any pointers regarding what is appreciated on this list and what is not. Hopefully, over time I will be able to make some form of useful, concrete code contributions in the form of patches or documentation, but I do realise it will take a lot of hands-on learning first. Trying to grok the discussions on this list seems like a big part of that.
Just dive in. We'll savage you when you get out of line :^). Seriously, as long as it's about development *of* rather than *with* Python, you should be OK. A couple of weeks lurking (or reading the list history) will tell you most things you need to know. regards Steve takes-all-sorts-to-make-a-world-ly y'rs - steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/
Tennessee Leeuwenburg wrote:
Hello all,
First a comment on-thread: I can't wait to get an ordered dictionary in the stdlib! The discussion regarding suggestions for the name appears to be ongoing. What about the name 'orderdict' instead of 'ordereddict'?. It doesn't contain the double-d, is slightly shorter, and I think a little more typo-friendly. Just my 2c, please feel free to ignore. OrderDict would of course be the alternative-casing version.
The naming discussion is largely shooting the breeze at this point - the OrderedDict naming follows PEP 8 and has a decent history of use in this context, and I don't believe the objections and alternatives are compelling enough to get anyone to write the code necessary to change it. For such a recent patch the "status quo wins by default" argument isn't as strong as it can sometimes be, but it still carries some weight. Someone might surprise me and come forward with a patch to change the name, but I really doubt it at this point.
Secondly, regarding this list: I would appreciate any pointers regarding what is appreciated on this list and what is not. Hopefully, over time I will be able to make some form of useful, concrete code contributions in the form of patches or documentation, but I do realise it will take a lot of hands-on learning first. Trying to grok the discussions on this list seems like a big part of that.
I'd say you're off to a good start - wanting to learn and understand the existing culture rather than demanding that the current list members adapt to *your* style is a great first step :) As for the culture itself... 'respect' is the main word that comes to my mind: - respect for other people's time in trying to post messages that are concise and to the point - respect for other people's points of view in trying to resolve design disagreements - respect for other people's abilities in assuming that errors are inadvertent mistakes or due to a small misunderstanding rather than a result of sheer incompetence - respect for Python's users in ensuring a variety of perspectives are taken into account when considering changes Also, you may have looked at this already, but if not, the developer page has some useful pointers: http://www.python.org/dev/ http://www.python.org/dev/culture/ Hope that helps! Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------
Gisle Aas wrote:
Instead of introducing a sorteddict I would instead suggest that the future should bring an odict with a sort method; possibly also keys_sorted and items_sorted methods.
Instead of odict.sorted(), that can be spelled: sorted(odict) # sort the keys sorted(odict.values()) # sort the items sorted(odict.items()) # sort the (key, value) pairs More complex variations are also possible. The idea of a SortedDict is that it should be sorted at all times, without needing an explicit sort method, e.g.: D = SortedDict(d=1, a=1, b=1) print D => SortedDict(a=1, b=1, d=1) D['c'] = 1 print D => SortedDict(a=1, b=1, c=1, d=1) If you need to call a sort method on the dict to generate the sorted version, you might as well just pass the values you want to sorted(). That's more flexible, as you can sort whatever you want by anything you like. I only know one use-case for a SortedDict: doctests. It's hard to use dicts in doctests, because when you print the dict, the items appear in arbitrary order. If you had a SortedDict, you could always predict what the dict would look like and use it in a doctest. Possibly there are other use-cases, but if so I don't know what they are. -- Steven
Gisle Aas wrote:
On Mar 4, 2009, at 9:01 , Glenn Linderman wrote:
On approximately 3/3/2009 11:22 PM, came the following characters from the keyboard of Raymond Hettinger:
Perhaps the terminology should be
ordereddict -- what we have here
sorteddict -- hypothetical future type that keeps itself sorted in key order +1
-1
Introducing the hypothetical sorteddict would serve to reduce the likelihood of ordereddict being interpreted as sorteddict among the small percentage of people that actually read the two lines that might mention it in the documentation, but wouldn't significantly aid the intuition of people who first encounter it in someone else's code.
And without an implementation, it would otherwise be documentation noise, not signal.
Instead of introducing a sorteddict I would instead suggest that the future should bring an odict with a sort method; possibly also keys_sorted and items_sorted methods.
I think this would simplify things and putting these methods into the odict documentation makes it clearer how it actually behaves for people that just scan the method index to get an impression of what the object is about.
How about making odict ordered by insertion order, then provide an optional argument for defining sorter? This optional argument must be a function/lambda/callable object and must be the first argument. a = odict(bloh='foo', blah='faa') a # odict([('bloh', 'foo'), ('blah', 'faa')]) b = odict(lambda a, b: (a[0] < b[0]), bloh='foo', blah='faa') b # sorted by key: odict([('blah', 'faa'), ('bloh', 'foo')]) c = odict(lambda a, b: (a[1] < b[1]), bloh='foo', blah='faa') c # sorted by value: odict([('blah', 'faa'), ('bloh', 'foo')]) b = odict(lambda a, b: (a[0] > b[0]), bloh='foo', blah='faa') b # sorted by key, descending: odict([('bloh', 'foo'), ('blah', 'faa')])
Lie Ryan wrote: How about making odict ordered by insertion order, then provide an
optional argument for defining sorter? This optional argument must be a function/lambda/callable object and must be the first argument.
As the PEP mentions (and Hrvoje brought up again already in this thread), a hash table (i.e. dict) probably isn't the right data structure to use as the basis for an "always sorted" container. In-memory databases, balanced trees, etc, etc. Further, unlike a more general "sorted" dictionary, an insertion ordered dict already has specific use cases in the standard library. ConfigParser will use it by default in 2.7/3.1 and namedtuple._asdict() is being changed in those versions to return an OrderedDict so that iterating over the result of _asdict() will process the fields in the same order as iterating over the tuple itself. It is also being added because an insertion ordered dictionary was the primary example for the new metaclass __prepare__ method introduced by PEP 3115. Adapting the example from that PEP: # The metaclass class OrderedClass(type): @classmethod def __prepare__(metacls, name, bases): # No keywords in this case return collections.OrderedDict() def __new__(cls, name, bases, classdict): # Note that we replace the classdict with a regular # dict before passing it to the superclass, so that we # don't continue to record the order after the class # has been created. result = type.__new__(cls, name, bases, dict(classdict)) result.member_names = list(classdict.keys()) return result # An instance of the metaclass class StructDef(metaclass=OrderedClass): # This dummy example uses types directly, but something # like struct module format codes may make more sense field1 = int field2 = float field3 = customType trailingField = str Unlike a normal class definition, the order of the field definitions in structure matters, and in the example above, this information is preserved by the metaclass. This can greatly simplify the process of defining types where the order of the fields matters (e.g. so the values can be serialised in the correct order for a binary translation of some kind). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------
Nick Coghlan wrote:
Lie Ryan wrote: How about making odict ordered by insertion order, then provide an
optional argument for defining sorter? This optional argument must be a function/lambda/callable object and must be the first argument.
or better yet, in the spirit of dumping cmp comparison like in list, the first optional argument would be a function that returns the sorting key of the object. If the optional argument is not specified, the current ordereddict semantic (by insertion order) will be used.
As the PEP mentions (and Hrvoje brought up again already in this thread), a hash table (i.e. dict) probably isn't the right data structure to use as the basis for an "always sorted" container. In-memory databases, balanced trees, etc, etc.
Isn't ordered dictionary essentially also an "always sorted" container? It is always sorted depending on the order of insertion? I can't see any technical reason why the data structure can't accommodate them both. Can you point me to a discussion on this?
Lie Ryan wrote:
Isn't ordered dictionary essentially also an "always sorted" container? It is always sorted depending on the order of insertion? I can't see any technical reason why the data structure can't accommodate them both. Can you point me to a discussion on this?
Appending an item at the end of a sequence is O(1), no search required. Inserting an item at a random 'sorted' point requires at best an O(logN) search. Insertion itself is O(1) to O(N) depending on the structure.
Terry Reedy wrote:
Lie Ryan wrote:
Isn't ordered dictionary essentially also an "always sorted" container? It is always sorted depending on the order of insertion? I can't see any technical reason why the data structure can't accommodate them both. Can you point me to a discussion on this?
Appending an item at the end of a sequence is O(1), no search required. Inserting an item at a random 'sorted' point requires at best an O(logN) search. Insertion itself is O(1) to O(N) depending on the structure.
Yeah, but with a proper algorithm[1] it is possible to get a O(1) append (which is the characteristic we want for insertion order dictionary, while falling back to O(log n) if we explicitly give comparer function (or comparison key extractor). [1] The insertion algorithm will test for where to insert from the end of the list. This way, insertion-order dict will still be O(1) (with an increased constant), else if custom order is specified insertion it will be O(n) #UNTESTED BECAUSE I DON'T HAVE PYTHON CURRENTLY # Note that it derives from OrderDict class MyOrderDict(OrderDict): def __init__(*args, **kwds): if len(args) > 2: raise TypeError('expected at most 2 arguments') if len(args) == 2: self._cmp, args = args[0], args[1:] else: self._cmp = lambda a, b: True if not hasattr(self, '_keys'): self._keys = [] self.update(*args, **kwds) def __setitem__(self, key, value): if key not in self: self._key.append(None) for i, k in enumerate(reversed(self._key)): i = -i - 1 if self._cmp((k, self[k]), (key, value)): self._key[i], self._key[i - 1] = k, key else: self._key[i] = k dict.__setitem__(self, key, value)
Lie Ryan wrote:
Isn't ordered dictionary essentially also an "always sorted" container? It is always sorted depending on the order of insertion? I can't see any technical reason why the data structure can't accommodate them both. Can you point me to a discussion on this?
My phrasing was a little ambiguous - "always sorted for an arbitrary key function" is better handled with something other than a hash map + additional bookkeeping due to the effect on the speed of insertion and deletion. With a specifically insertion-ordered dict, only deletion is really slowed down by the additional bookkeeping: it drops to O(n) due to the need to find and remove the key being deleted from the sequence of keys as well as from the hash map). As Terry noted, supporting arbitrary sort orders would slow down insertion as well. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------
Glenn Linderman wrote:
FIFOdict ? Yeah, that blows the capitalization scheme, way, way out. [...] It is suggestive of queue behavior, and the items are a queue if looked at from insertion, and traversal perspectives, if I understand correctly.
Why is this relevant? Insertion and traversal are only two parts of dict behaviour, whether ordered, sorted or otherwise. You can lookup, delete or modify items anywhere in the dict, not just at the ends. Doesn't sound very queue-like to me. [...]
FWIW, PEP 372 has links to seven other independent implementations and they all have names that are some variant spelling OrderedDict except for one which goes by the mysterious name of StableDict.
Well, just because six other independent implementations use a name with connotations that they don't live up to is no reason to perpetuate such foolishness, nor introduce it into the Python stdlib.
I don't believe the name is any more misleading than "dict" itself, or "str". It is a standard well-known name. From Google: Results 1 - 10 of about 264 for StableDict Results 1 - 10 of about 6,880 for OrderedDict Results 1 - 10 of about 21,700 for ODict (I have made no effort to exclude false positives.) Yes, if you are a Martian or somebody learning to program for the first time, you have to learn what an ordered dict is. So what? You had to learn what a "str" was the first time you came across one too.
StableDict, eh? That's not so mysterious, perhaps, if you think of stable sorts^H^H^H^H^H (whoops, there's the wrong connotation rearing its ugly head again, sorry).
What does it mean to say a dict is stable? That is doesn't decay and rot away if you leave it alone? Do items evaporate out of ordinary dicts if you leave them alone for long enough? That once you add an item, you can't remove it or mutate it? It's not clear what the Stable in StableDict could mean.
I didn't expect FIFOdict to be an extremely useful suggestion, but I wanted to make the point that if the name has an erroneous connotation, use a name that doesn't.
FIFOdict is *far* more misleading, as it erroneously suggests that you can't (or at least shouldn't) access elements in the middle of the dict.
From tree-walking, perhaps people would intuit the right connotations from InOrderDict which is no longer than ordereddict, but usually the tree is kept sorted too, so I'm afraid it might not be sufficient.
No, I'm sorry, that's wrong. Inorder traversal of a binary tree is nothing like order-of-insertion traversal of a dict. node = 'a' node.right = 'c' node.left = 'b' Inorder traversal of node gives: b, a, c. Order-of-insertion traversal gives: a, c, b.
C'mon folks, brainstorm, don't complain about ordereddict if you can't come up with some alternatives for discussion!!!
There are two good alternatives: OrderedDict and odict, or as Raymond puts it, green with pink polka dots versus pink with green polka dots. I don't think there's much point in suggesting fluorescent orange with brown and grey stripes as well. -- Steven
On Wed, Mar 4, 2009 at 3:01 AM, Glenn Linderman <v+python@g.nevcal.com> wrote:
C'mon folks, brainstorm, don't complain about ordereddict if you can't come up with some alternatives for discussion!!! (and some reasons why the suggestions might be good or bad) Even your bad ideas might trigger a good name in someone else's head...
TemporalDict -- Since the order of insertion is important SerialDict -- From Websters: of, relating to, consisting of, or arranged in a series, rank, or row <serial order> -- Benji York
Am 04.03.2009 14:25, Benji York schrieb:
On Wed, Mar 4, 2009 at 3:01 AM, Glenn Linderman <v+python@g.nevcal.com> wrote:
C'mon folks, brainstorm, don't complain about ordereddict if you can't come up with some alternatives for discussion!!! (and some reasons why the suggestions might be good or bad) Even your bad ideas might trigger a good name in someone else's head...
TemporalDict -- Since the order of insertion is important SerialDict -- From Websters: of, relating to, consisting of, or arranged in a series, rank, or row <serial order>
Because the class is designed to only support insertion order and not any other sorting why choose a generic name that could also describe a class that supports a different order? I'd prefer encoding the order in the class name, therefore I suggest (Ins|Insertion)(Order|Ordered)Dict, e.g. InsOrderDict. Abbreviating the first group to simply I probably is too confusing because of the use of I as a prefix for interfaces. Dennis Benzinger
Dennis Benzinger wrote:
I'd prefer encoding the order in the class name, therefore I suggest (Ins|Insertion)(Order|Ordered)Dict, e.g. InsOrderDict. Abbreviating the first group to simply I probably is too confusing because of the use of I as a prefix for interfaces.
Except I just don't see this proliferation of dict types with different sort orders ever happening. The distinction between OrderedDict and dict is that the order of keys()/values()/items() isn't arbitrary the way it is in a regular dict - there's a defined order that will always be used. That's all the name tells you - if someone assumes they know what that ordering is without actually looking at the documentation (and gets it wrong as a result), then I don't see how that is any different from the fact that someone might mistakenly assume that list.sort() puts the items in descending order instead of ascending order. For other sort orders, it seems far more likely to me that a collections.SortedMap type would be added at some point in the future that accepts a key function like the one accepted by sorted() and list.sort(). Such a data type would make different trade-offs between insertion, deletion and lookup speeds than those made in the hash map based OrderedDict. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia ---------------------------------------------------------------
Hi Nick! Am 04.03.2009 22:34, Nick Coghlan schrieb:
Dennis Benzinger wrote:
I'd prefer encoding the order in the class name, therefore I suggest (Ins|Insertion)(Order|Ordered)Dict, e.g. InsOrderDict. Abbreviating the first group to simply I probably is too confusing because of the use of I as a prefix for interfaces.
Except I just don't see this proliferation of dict types with different sort orders ever happening.
Maybe there's a misunderstanding because I don't see it either. I was trying to suggest four alternative names for the OrderedDict class. I don't prefer encoding every possible sort order into the class name. I just wanted to improve the name of OrderedDict.
The distinction between OrderedDict and dict is that the order of keys()/values()/items() isn't arbitrary the way it is in a regular dict - there's a defined order that will always be used.
Yes, the insertion order.
That's all the name tells you - if someone assumes they know what that ordering is without actually looking at the documentation (and gets it wrong as a result), then I don't see how that is any different from the fact that someone might mistakenly assume that list.sort() puts the items in descending order instead of ascending order.
And because that's all the name tells you I suggested to make the name more clear by prepending Ins or Insertion.
For other sort orders, it seems far more likely to me that a collections.SortedMap type would be added at some point in the future that accepts a key function like the one accepted by sorted() and list.sort(). Such a data type would make different trade-offs between insertion, deletion and lookup speeds than those made in the hash map based OrderedDict. [...]
Yes. Dennis Benzinger
Raymond Hettinger wrote: [...]
FWIW, PEP 372 has links to seven other independent implementations and they all have names that are some variant spelling OrderedDict except for one which goes by the mysterious name of StableDict.
Am still +1 on painting the class green with pink polka dots, but I'm starting to appreciate why others are insisting on pink with green polka dots ;-)
This will be no surprise to those who have seen the many discussions on ordered dicts that c.l.py has spawned over the years. regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/
Raymond Hettinger wrote:
Perhaps the terminology should be
ordereddict -- what we have here
sorteddict -- hypothetical future type that keeps itself sorted in key order
+1
FIFOdict ? Yeah, that blows the capitalization scheme, way, way out.
Issues: * The popitem() method is LIFO. * In a non-popping context, there is no OUT. It just stores. * FIFO is more suggestive of queue behavior which does not apply here. * Stores to existing keys don't go at the end; they leave the order unchanged.
FWIW, PEP 372 has links to seven other independent implementations and they all have names that are some variant spelling OrderedDict except for one which goes by the mysterious name of StableDict.
Am still +1 on painting the class green with pink polka dots, but I'm starting to appreciate why others are insisting on pink with green polka dots ;-)
historydict? regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/
Steve Holden wrote: > Raymond Hettinger wrote: >>>> Perhaps the terminology should be >>>> >>>> ordereddict -- what we have here >>>> >>>> sorteddict -- hypothetical future type that keeps >>>> itself sorted in key order >> +1 >> >> >>> FIFOdict ? Yeah, that blows the capitalization scheme, way, way out. >> Issues: >> * The popitem() method is LIFO. >> * In a non-popping context, there is no OUT. It just stores. >> * FIFO is more suggestive of queue behavior which does not apply here. >> * Stores to existing keys don't go at the end; they leave the order >> unchanged. >> >> FWIW, PEP 372 has links to seven other independent implementations and >> they all have names that are some variant spelling OrderedDict except >> for one which goes by the mysterious name of StableDict. >> >> Am still +1 on painting the class green with pink polka dots, but I'm >> starting to appreciate why others are insisting on pink with green polka >> dots ;-) >> > historydict? agedict?
On Wed, 4 Mar 2009 at 23:37, Lie Ryan wrote:
> Steve Holden wrote:
>> Raymond Hettinger wrote:
>> > > > Perhaps the terminology should be
>> > > >
>> > > > ordereddict -- what we have here
>> > > >
>> > > > sorteddict -- hypothetical future type that keeps
>> > > > itself sorted in key order
>> > +1
>> >
>> >
>> > > FIFOdict ? Yeah, that blows the capitalization scheme, way, way out.
>> > Issues:
>> > * The popitem() method is LIFO.
>> > * In a non-popping context, there is no OUT. It just stores.
>> > * FIFO is more suggestive of queue behavior which does not apply here.
>> > * Stores to existing keys don't go at the end; they leave the order
>> > unchanged.
>> >
>> > FWIW, PEP 372 has links to seven other independent implementations and
>> > they all have names that are some variant spelling OrderedDict except
>> > for one which goes by the mysterious name of StableDict.
>> >
>> > Am still +1 on painting the class green with pink polka dots, but I'm
>> > starting to appreciate why others are insisting on pink with green polka
>> > dots ;-)
>> >
>> historydict?
>
> agedict?
I actually like StableDict best. When I hear that I think, "ah, the
key order is stable in the face of insertions, unlike a regular dict".
Nor can I at the moment think of an alternative explanation of what a
"StableDict" might be.
That said, I have no problem with keeping OrderedDict as the name.
("Ordered does not mean sorted, it means insertion order preserving"
may become a FQA (Frequent Question Answer :), but it is short and
clear and takes no longer than explaining what a StableDict _is_.)
Although, that might be another argument in favor of StableDict: since
unless you think what I wrote above you aren't going to have a clue what
it is, someone reading code and encountering it would be more likely to
look it up, whereas with OrderedDict someone is more likely to assume they
know what it is and get confused for a little while before looking it up.
Do I feel strongly enough about this to write a patch? No :)
--RDM
<rdmurray <at> bitdance.com> writes:
I actually like StableDict best. When I hear that I think, "ah, the key order is stable in the face of insertions, unlike a regular dict". Nor can I at the moment think of an alternative explanation of what a "StableDict" might be.
That said, I have no problem with keeping OrderedDict as the name. ("Ordered does not mean sorted, it means insertion order preserving" may become a FQA (Frequent Question Answer :), but it is short and clear and takes no longer than explaining what a StableDict _is_.)
Thanks to Python (and Raymond :-)), I now know what polka dots are. Python-improves-my-English-skills'ly yours, Antoine.
On Wed, Mar 4, 2009 at 7:53 AM, <rdmurray@bitdance.com> wrote:
I actually like StableDict best. When I hear that I think, "ah, the key order is stable in the face of insertions, unlike a regular dict". Nor can I at the moment think of an alternative explanation of what a "StableDict" might be.
+1 -- Cheers, Leif
On Wed, Mar 4, 2009 at 7:53 AM, <rdmurray@bitdance.com> wrote:
I actually like StableDict best. When I hear that I think, "ah, the key order is stable in the face of insertions, unlike a regular dict". Nor can I at the moment think of an alternative explanation of what a "StableDict" might be.
Hmm, perhaps a better explanation than a hasty +1: "stabledict" makes me think of merge sort, being a stable sort. In the same way that merge sort doesn't needlessly swap elements while sorting, stabledict might be thought to not "needlessly" swap elements while {inserting, deleting}. I also can't think of an alternative explanation, so thus far, it's resistant to false positive semantics. -- Cheers, Leif
Leif Walsh wrote:
On Wed, Mar 4, 2009 at 7:53 AM, <rdmurray@bitdance.com> wrote:
I actually like StableDict best. When I hear that I think, "ah, the key order is stable in the face of insertions, unlike a regular dict". Nor can I at the moment think of an alternative explanation of what a "StableDict" might be.
Hmm, perhaps a better explanation than a hasty +1:
"stabledict" makes me think of merge sort, being a stable sort.
Why merge sort in particular? Why not bubble sort, heap sort, insertion sort or any one of many other stable sorts? Is this analogy really simpler than merely learning the fact that the dict keys are kept in the order they are inserted? It's not a very difficult concept. Why are we complicating it by inventing obscure, complicated analogies with utterly unrelated functions?
In the same way that merge sort doesn't needlessly swap elements while sorting, stabledict might be thought to not "needlessly" swap elements while {inserting, deleting}.
You're drawing an awfully long bow here. One might equally argue that in the same way that bubble sort does lots and lots of swapping, stabledict might be thought to be horribly inefficient and slow.
I also can't think of an alternative explanation, so thus far, it's resistant to false positive semantics.
"The keys don't expire with time." "It's stable against accidental deletions." "It's stable against accidentally over-writing values." -- Steven
Steven D'Aprano wrote:
I also can't think of an alternative explanation, so thus far, it's resistant to false positive semantics.
"The keys don't expire with time." "It's stable against accidental deletions." "It's stable against accidentally over-writing values."
Add to that: "The StableDict is stable because it has no bugs, unlike the buggy dict"
rdmurray@bitdance.com wrote:
I actually like StableDict best. When I hear that I think, "ah, the key order is stable in the face of insertions, unlike a regular dict".
But it still doesn't convey what the ordering actually *is*. -- Greg
On Wed, Mar 4, 2009 at 1:44 PM, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
rdmurray@bitdance.com wrote:
I actually like StableDict best. When I hear that I think, "ah, the key order is stable in the face of insertions, unlike a regular dict".
But it still doesn't convey what the ordering actually *is*.
Please, stick with OrderedDict. That's the name used historically by most people who independently reinvented this functionality. -- --Guido van Rossum (home page: http://www.python.org/~guido/)
On Wed, 4 Mar 2009 05:23:33 pm Glenn Linderman wrote:
The problem with the ordereddict/OrderedDict/odict is that there are way too many possible orderings, and without being more specific (InsertionSequenceOrderPreservingDictionary) people are doing to think "sort" when they hear "ordered".
For what it's worth, the first time I heard the term "ordered dictionary", I assumed it would be a dict where the keys are kept in sorted order. But so what? Making things easy is an admirable goal, but we shouldn't lose sight of the fact that Python is a programming language, not a door handle. There's no requirement that every last feature is easy to intuit for a naive user. It's okay if people sometimes guess wrong, so long as they have opportunity to learn better. Speaking as an ignorant and lazy programmer, being user-friendly is one thing, but molly-coddling the ignorant and lazy is another. Especially when it takes just a few seconds to type "import collections; help(collections.odict)" and learn that the O stands for ordered, and that the order is specifically order of insertion rather than lexicographic order. Having good help text is user-friendly. Naming the class InsertionSequenceOrderPreservingDictionary is just dumbing down at the cost of usability. I trust this wasn't a serious suggestion, but just in case it was, I'll point out that we have dict instead of UnorderedKeyValueMapping. Does anyone think that people find Python harder to learn because of that choice?
I think FIFOdict is a reasonable abbreviation for InsertionSequenceOrderPreservingDictionary :)
I see your smiley, but in my opinion, the sort of programmer who can't work out what an OrderedDict (or odict) is, given the name, the doc string and the Internet, is going to have even more trouble working out what FIFOdict means. I have no strong feelings either way between odict and OrderedDict. PEP 8 seems to demand OrderedDict, but I actually prefer odict on the basis that an ordered dictionary feels like a fundamental data structure like str, list and dict rather than a specialist class like HTTPBasicAuthHandler. (I realise that "fundamental data structure" is not a well-defined category.) I look forward to the day OrderedDict becomes a built-in so it can be renamed odict :) -- Steven
Hi, Georg Brandl <g.brandl <at> gmx.net> writes:
We're already quite inconsistent with type name casing in the collections module, so it wouldn't matter so much. (Though I'd find symmetry with defaultdict pleasing as well.) We either have the way to be consistent with defaultdict and dict or with Counter, MutableMapping etc.
I think it's a bit too chaotic already to make a fair decision here. If we seriously consider a C implementation it would probably be a good idea to call it `odict`. C-Classes are usually lower cased as far as I can see. Regards, Armin
2009/3/2 Armin Ronacher <armin.ronacher@active-4.com>:
Hi,
Georg Brandl <g.brandl <at> gmx.net> writes:
We're already quite inconsistent with type name casing in the collections module, so it wouldn't matter so much. (Though I'd find symmetry with defaultdict pleasing as well.) We either have the way to be consistent with defaultdict and dict or with Counter, MutableMapping etc.
I think "normal" class names are fine for ABCs, but I brought it up because the other dictionary class in collections had a all lowername.
I think it's a bit too chaotic already to make a fair decision here. If we seriously consider a C implementation it would probably be a good idea to call it `odict`. C-Classes are usually lower cased as far as I can see.
I don't implementation language should determine naming. -- Regards, Benjamin
My preference is OrderedDict. That says that it is a pure python class like Counter, UserDict, UserList, MutableMapping and other collections classes. It is clear and explicit in its intention and doesn't make you try to remember what the o in odict stands for. Raymond
2009/3/2 Raymond Hettinger <python@rcn.com>:
My preference is OrderedDict. That says that it is a pure python class like Counter, UserDict, UserList, MutableMapping and other collections classes.
I don't understand why implementation language should have any significance in naming. Classes should be able to be implemented in any language transparently.
It is clear and explicit in its intention and doesn't make you try to remember what the o in odict stands for.
I agree and that's why I propose "ordereddict" -- Regards, Benjamin
Benjamin Peterson wrote:
2009/3/1 Armin Ronacher <armin.ronacher@active-4.com>: [...]
The corresponding issue in the tracker: http://bugs.python.org/issue5397 Link to the PEP: http://www.python.org/dev/peps/pep-0372/
Anything else that should be done?
Have you considered naming? I would think that "odict" or "ordereddict" would be more consistent with other collections names especially "defaultdict".
Surely that's just a thinko in the subject line? The PEP specifies "ordered dictionary" and nobody has been talking about "directories". regards Steve -- Steve Holden +1 571 484 6266 +1 800 494 3119 Holden Web LLC http://www.holdenweb.com/
Steve Holden <steve <at> holdenweb.com> writes:
Surely that's just a thinko in the subject line? The PEP specifies "ordered dictionary" and nobody has been talking about "directories". Actually, the initial version of the PEP had that typo in the topic. Guess I copy pasted wrong again: http://www.google.com/search?q=%22adding+an+ordered+directory%22
Regards, Armin
participants (28)
-
"Martin v. Löwis" -
Antoine Pitrou -
Armin Ronacher -
Barry Warsaw -
Benjamin Peterson -
Benji York -
Brett Cannon -
Dennis Benzinger -
Dirkjan Ochtman -
Eric Smith -
Georg Brandl -
Giovanni Bajo -
Gisle Aas -
Glenn Linderman -
Greg Ewing -
Guido van Rossum -
Ivan Krstić -
Jean-Paul Calderone -
Leif Walsh -
Lie Ryan -
Nick Coghlan -
Paul Moore -
Raymond Hettinger -
rdmurray@bitdance.com -
Steve Holden -
Steven D'Aprano -
Tennessee Leeuwenburg -
Terry Reedy