Wandering Thoughts archives


Nested conditional expressions in Python (and code golf)

Recently I had an occasion to use a nested (or chained) conditional expression. I haven't used conditional expressions much, so at first I just wrote out what struck me as the obvious way:

res = a.field1 if a.field1 else obj.field2 if obj else None

(The goal is to use a.field1 if it's got a value, obj.field2 if obj is there, and otherwise None.)

Then I paused to ask myself if this was going to have the right grouping of evaluation; testing said that it did, to my pleasant surprise. It's always nice when Python behaves the way I expected it to and my naive code works. That it happens so often is one of the reasons that I like Python so much.

While this nested conditional expression was the obvious way to write the expression (since I was converting it from what would otherwise be a nested if), it's possible to be more clever. The simple way is to get rid of the actual conditional expressions in favour of exploiting the side effects of or and and:

res = a.field1 or (obj and obj.field2) or None

(Given when I'm trying to do here this doesn't suffer from the usual problem of (ab)using and and or this way.)

Of course we can golf this code further:

res = a.field1 or getattr(obj, 'field2', None)

To my mind this is well over the line into excessively clever, partly because it mixes two different ways to refer to fields in the same expression. Even the first condensed version is not something I'm entirely happy with (partly because it's subtly different than the straightforward version using conditional expressions). So my initial version is going to stay in my code.

(I think I've basically recanted on my views about avoiding conditional expressions in Python by now. Time moves on and I get used to things.)

python/NestedConditionalExprs written at 22:49:29; Add Comment

Page tools: See As Normal.
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.