Forgetting "()" when calling methods

Alex Martelli aleax at aleax.it
Mon Apr 28 04:02:20 EDT 2003


<posted & mailed>

Tim Peters wrote:

> [Terry Reedy]
>> ...
>> At one time, it was easy for anyone to get 100% on a quiz like 'how
>> many of the following lists can Python sort?".
> 
> OTOH, how many would have scored 100% if also asked what the result of
> sorting would be?  I'm not sure anyone could have.  For years, ints came
> out "less than" lists, which in turn came out "less than" longs, so that
> 
>     [10, [9], 7L, 8]
> 
> was considered to be "in sorted order" as-is.  It was something like 7
> years before someone finally noticed how nuts that was.

*Blink* -- I don't get it.  Even if int < list < long, how CAN the
two int's here be ``considered in sorted order''???

> two within a single program run).  When that's so, sorting brings objects
> of
> the same type next to each other, and that's about it.  But if that's "the
> use case" (if it isn't, what is the use case?!), it's much more efficient
> (O(N) vs O(N log N)) to segregate objects via a dict mapping type to a
> list of objects with that type.

Here is a typical use case: prettyprinting a dictionary.

>>> import pprint
>>> adic = dict.fromkeys([ i*1j for i in range(4) ])
>>> pprint.pprint(adic)
{0j: None, 3j: None, 1j: None, 2j: None}

So far so good -- we CAN prettyprint a dictionary.  I'd rather have
the keys show (within a prettyprint operation only) in an order that
seems less arbitrary, but, oh well, can't have everything, I guess.

So, let's prettyprint a slightly bigger dict...:

>>> adic = dict.fromkeys([ i*1j for i in range(8) ])
>>> pprint.pprint(adic)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/local/lib/python2.3/pprint.py", line 54, in pprint
    printer.pprint(object)
  File "/usr/local/lib/python2.3/pprint.py", line 105, in pprint
    self._stream.write(self.pformat(object) + "\n")
  File "/usr/local/lib/python2.3/pprint.py", line 109, in pformat
    self._format(object, sio, 0, 0, {}, 0)
  File "/usr/local/lib/python2.3/pprint.py", line 142, in _format
    items.sort()
TypeError: cannot compare complex numbers using <, <=, >, >=
>>>

Oops!  We can't prettyprint it any more -- kaBOOM.

It's perfectly natural to want to sort a dict's keys in order to
prettyprint it -- as you see, the standard library's own pprint
does it (but only if the dict is large-ish).  What one would LIKE
to happen is to have the keys come out bunched by types and in
SOME vaguely sensible order within each type (but probably with
number-types mixed together, and string-types too) -- but "pretty" 
may be in the eye of the beholder, so we can quibble about that
separately, I guess.

However, it seems totally arbitrary to me that the standard
library's pprint.pprint should raise an exception just because 
the user's trying to prettyprint a dictionary with some complex
numbers as keys.  I guess one could class this as a bug in
pprint, but from my POV what it does is highlight a typical
case in which the inability to ask "just sort this stuff so
it displays in an order that doesn't appear totally random"
*hurts*, and hurts pretty badly too.

What's the ADVANTAGE gained, worth breaking prettyprinting for?

It seems to me it's basically one of "purity" -- that 1.5.2
was far more pragmatic in this regard.  I know I'm not gonna get
the pragmatism back, sigh, but is it SO hard to understand why
I would want it?!  I need to show beginners what's going to
result from various operations -- and the fact that when the
results are dicts they display in random-ish order is a small
but unpleasant distraction from whatever point I'm trying to
teach -- so, I might want to (e.g.) hook displayhook to give
"pretty" results rather than raw repr's.  pprint.pprint might
be a good starting point... BUT it's broken by this purity-
based "enhancement"...


Alex





More information about the Python-list mailing list