For review: PEP 308 - If-then-else expression

Andrew Dalke adalke at mindspring.com
Mon Feb 10 00:13:22 EST 2003


James J. Besemer <jb at cascade-sys.com>:
> A quick perusal of Python interpreter source code reveals several hundred
> uses of the ?: operator.

> Clearly the estimed BDFL evidently finds C's ?: as is to be fairly useful,
at
> least sufficiently useful to employ it routinely.

> Include/abstract.h:
> (PyList_Check(o) ? PyList_GET_SIZE(o) : PyTuple_GET_SIZE(o))
> (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i))

Without looking at the code, this is an optimization trick used for
performance, to get the given property from a list or tuple without
going through the full object interface.  It is a form of run-time type
checking.

This is done because C does not have classes.  If it has classes, then
this would be a simple method invocation.

> Modules/_hotshot.c:
> result = (self->logfp == NULL) ? Py_True : Py_False;
> (self->frametimings ? "yes" : "no"));
> (self->lineevents ? "yes" : "no"));

The first of this would be replaced by a bool().  The other two are
cases where a if/else expression in Python would be more succinct.

> Modules/_sre.c:
> #define SRE_LOC_IS_DIGIT(ch) ((ch) < 256 ? isdigit((ch)) : 0)
> #define SRE_LOC_IS_SPACE(ch) ((ch) < 256 ? isspace((ch)) : 0)
> #define SRE_LOC_IS_ALNUM(ch) ((ch) < 256 ? isalnum((ch)) : 0)

The argument for a if/else expression is:
  - more readable
  - don't need to introduce a new name
  - don't need the function call overhead
  - obeys short-circuit logic

I agree that this is more readable for me (with nearly 15 years of
C experience).  I do point out that this creates a new name and uses
C's macro system to get around uncertainties about if a given C
implementation will inline those functions.  Also, in this case, short
circuiting is somewhat important.

Were this used in Python, the inlining would be done by hand, which
means having "isdigit(ch) if ch < 256 else 0" be used many times instead
of simply using "SRE_LOC_IS_DIGIT".  Doing this (manual inlining
instead of using a function call) in Python would then mean less
maintainable and not more maintainable code.

So I think in this case the ?: is appropriate for C but if/else expression
is not appropriate for Python.

> Modules/binascii.c:
> c = (c>9) ? c+'a'-10 : c + '0';

In Python this would be "0123456789abcdef"[c]
(extend as needed if this needs more than hex characters)
Also, I think this could be done in C as well.

> Modules/cPickle.c:
> size = ((n < 32) ? 32 : n);

In Python, size = max(n, 32)

> [many, many more where these came from.]
>
> If it's good enough for Python, the implementation -- then it's good
enough
> for Python, the language.

My point, given elsewhere in this very long thread, is that
constructs which are appropriate for ?: in C are not necessarily
appropriate for Python, since other solution implementation are
possible.

So of the examples listed above, they can be categorized as

1) use a method (instead of manual dispatch)
2) use a bool constructor
3) 2 appropriate uses
4) makes things less maintainable but faster
5) index into a string as a list
6) max function

I don't think anyone is likely to use #1 in Python code.

I do think most people with experience in C/Perl/etc. which have
a ternary if/else expression will likely use it in lieu of a "proper"
Python solution for #4 (because of the performance) and
#5 (because of lack of practice with this idiom, even though
C allows it as well).  Give this a 75% chance.

I also think that many people will use it instead of a more
"Pythonic" approach for #2 and #6, because those require
knowing more about Python than a coder new to Python
might expect.  Give these a 25% chance.

Counting this up, if the Python source code is used as a
basis to estimate use and misuse of if/else for Python programs
then
  proper uses = 2 + 2 * (1-0.75) + 2 * (1-0.25) = 4
improper uses = 6 - 4 = 2

In other words, my interpretation of your analysis suggests
that there will be a 33% MISUSE rate of the if/else expression
feature in Python code.

                    Andrew
                    dalke at dalkescientific.com






More information about the Python-list mailing list