[Python-ideas] Add orderedset as set(iterable, *, ordered=False) and similarly for frozenset.

Steven D'Aprano steve at pearwood.info
Fri Feb 6 01:10:30 CET 2015


On Wed, Feb 04, 2015 at 01:14:14PM -0800, Neil Girdhar wrote:
> Hundreds of people want an orderedset 
> (http://stackoverflow.com/questions/1653970/does-python-have-an-ordered-set) 
> and yet the ordered sets that are in PyPI (oset, ordered-set) are 
> incomplete.  Please consider adding an ordered set that has *all* of the 
> same functionality as set.

I think you have this backwards: more likely, first you find a complete 
implementation on PyPI, then you propose it for the standard library.


> The only major design decision is (I think) whether to store the elements 
> in a linked list or dynamic vector.

That's an implementation detail and therefore irrelevant (in the sense 
that it is subject to change without affecting code that uses ordered 
sets).

I think there are plenty of other major design decisions to be made. 
What's the union between a regular set and an ordered set? Is there a 
frozen ordered set? Do ordered sets compare unequal if they differ only 
in order (like lists)?


> My personal preference is to specify the ordered set via a flag to the 
> constructor, which can be intercepted by __new__ to return a different 
> object type as necessary.

-1 on a flag to the constructor.

I don't know if this rule (well, guideline) has a formal name anywhere, 
so I'm going to call it Guido's Rule: no constant mode arguments. I 
think this is a powerful design principle.

Functions or methods (including constructors) should not take arguments 
which, when given, are invariably supplied as constants. This especially 
goes for "mode" arguments, usually a flag, where the implemention of the 
function then looks something like this:

def thing(arg, flag=True):
    if flag:
        return this(arg)
    else:
        return that(arg)

In cases like this, you should expose this and that as distinct 
functions.

(If somebody -- Guido? -- would like to propose a cleaner explanation 
for the rule, I suggest we put it somewhere in the documention. Perhaps 
in the FAQs.)

Examples:

(1) We have list and tuple as separate functions, not sequences(*args, 
*, mutable=False).

(2) str and unicode (str and bytes), not str(obj, unicode=True).

(3) pairs of (sin, sin), (cos, acos), (tan, atan) functions, rather than 
sin(x, inverse=False). For that matter, same with sin/sinh etc.


Note that this is a "should not", not "must not": exceptions are allowed 
where the API clearly improved by it:

sorted(seq, reversed=True) rather than sorted/reverse_sorted.


> (If anyone wants to add a complete ordered set to PyPI that would also be 
> very useful for me!)

I'm sure it would be very useful to lots of people. Perhaps you could 
scratch your own itch and solve their problem at the same time?


-- 
Steve


More information about the Python-ideas mailing list