[Python-Dev] PEP 218 (sets); moving set.py to Lib

Oren Tirosh oren-py-d@hishome.net
Sat, 17 Aug 2002 14:34:35 -0400

On Fri, Aug 16, 2002 at 06:32:15PM -0400, Tim Peters wrote:
> > - The set constructors have an optional second argument, sort_repr,
> >   defaulting to False, which decides whether the elements are sorted
> >   when str() or repr() is taken.  I'm not sure if there would be
> >   negative consequences of removing this argument and always sorting
> >   the string representation.
> I'd rather you left this alone.  Being sortable is a much stronger
> requirement on set elements than just supporting __hash__ and __eq__, and,
> e.g., it would suck if I could create a set of complex numbers but couldn't
> print it(!).

How about sorting with this comparison function:

errors = (TypeError, ...?)

def cmpval(x):
        cmp(0, x)
    except errors:
            h = hash(x)
        except errors:
            h = -1
        return (1, h, id(x))
    return (0, x)

def robust_cmp(a,b):
        return cmp(a,b)
    except errors:
            return cmp(cmpval(a), cmpval(b))
        except errors:
            return 0

>>> l=[3j, 2j, 4, 4j, 1, 2, 1j, 3]
>>> l.sort(robust_cmp)
>>> l
[1, 2, 3, 4, 1j, 2j, 3j, 4j]

It's equivalent to standard cmp if no errors are encountered. For lists
containing uncomparable objects it produces a pretty consistent order.
It's not perfect but should be good enough for aesthetic purposes.