I have this
bc = 'off'
if c.page == 'blog':
bc = 'on'
print(bc)
Is there a more pythonic (and/or shorter) way of writing this in Python?
-
9Do you have to use 'on' and 'off'? Could this info be repesented with just a boolean, I mean bc = (c.page == 'blog') is much better.u0b34a0f6ae– u0b34a0f6ae2009年08月23日 21:19:29 +00:00Commented Aug 23, 2009 at 21:19
6 Answers 6
Shortest one should be:
bc = 'on' if c.page=='blog' else 'off'
Generally this might look a bit confusing, so you should only use it when it is clear what it means. Don't use it for big boolean clauses, since it begins to look ugly fast.
Comments
This is:
- definitely shorter
- arguably Pythonic (pre-Python 2.5, which introduced the controversial
X if Z else Ysyntax) questionably readable. With those caveats in mind, here it goes:
bc = ("off","on")[c.page=="blog"]
EDIT: As per request, the generalized form is:
result = (on_false, on_true)[condition]
Explanation: condition can be anything that evaluates to a Boolean. It is then treated as an integer since it is used to index the tuple: False == 0, True == 1, which then selects the right item from the tuple.
7 Comments
("off", "on") is a tuple and c.page=="blog" evaluates to the index of the element that is being accessedX if Z else Y is that if Z is false we only evaluate Y not X so it fails for example if key not in dictionary: adict[ k ] if adict.__contains( k ) else kWell, not being a python guy please take this with a huge grain of salt, but having written (and, with more difficulty, read) a lot of clever code over the years, I find myself with a strong preference now for readable code. I got the gist of what your original code was doing even though I'm a nobody as a Python guy. To be sure, you could hide it and maybe impress a Python wonk or two, but why?
6 Comments
if freiksenet mentions doesn't have these problems: it takes some getting used to, but it's a style much more amenable to maintenance than raw branches.You could use an inline if statement:
>>> cpage = 'blog'
>>> bc = 'on' if cpage == 'blog' else 'off'
>>> bc
'on'
>>> cpage = 'asdf'
>>> bc = 'on' if cpage == 'blog' else 'off'
>>> bc
'off'
There's a bit of a writeup on that feature at this blog, and the relevant PEP is PEP308. The inline if statement was introduced in Python 2.5.
This one is less pythonic, but you can use and/or in this fashion:
>>> cpage = 'asdf'
>>> bc = (cpage == 'blog') and 'on' or 'off'
>>> bc
'off'
>>> cpage = 'blog'
>>> bc = (cpage == 'blog') and 'on' or 'off'
>>> bc
'on'
This one is used more often in lambda statements than on a line by itself, but the form
A and B or C
is similar to
if A:
return B
else:
return C
The major caveat to this method (as PEP 308 mentions) is that it returns C when B is false.
5 Comments
Another possibility is to use a dict if you can compute the values outside of the function that accesses them (i.e. the values are static, which also addresses the evaluation issue in scrible's answer's comments).
want_bc = {True: "on", False: "off"}
# ...
bc = want_bc[c.page == "blog"]
I prefer this and/or the tuple indexing solutions under the general rubric of preferring computation to testing.
Comments
You can use,
a = b if c else d
but if you are using a python version prior to 2.5,
bc = c.page == "blog" and "on" or "off"
can do the trick also.