for variable in angles if options.angle else comps:
I have a program that does some calculations for multiple
different values of a certain quantity. I wanted to either
write a second program that would hold the first quantity
fixed and loop over a different one, or to extend the
first to do either of those based on a command-line option.
While noodling around, I thought "what about --" and came up
with the following idea:
============================================================
if options.angle:
angles = [0.05*k for k in range(7)]
else:
comps = [0.1*k for k in range(6)]
for variable in angles if options.angle else comps:
if options.angle:
angle = variable
else:
X_C = variable * -X_L
junk = sys.stdout.write( "%4.2f %4.3f\n" % (angle,X_C) )
# Hard part elided for clarity ============================================================
I was surprised to see that one could actually write a
for-loop like that, although it tickled my inner hacker.
What I'd like to know is: Is this an egregious abuse of the
language, or is it perfectly pythonic?
Opinions, and even violent disagreement, are solicited.
, is fine, but I think what would be a bit clearer might be,
variables = angles if options.angle else comps
for variable in variables:
.
for variable in angles if options.angle else comps:
Just today, I wrote something similar:
if mode == "file":
storage_context = FileStorage()
elif mode == "database":
storage_context = DatabaseStorage( server )
Michael F. Stemper wrote:
============================================================
if options.angle:
angles = [0.05*k for k in range(7)]
else:
comps = [0.1*k for k in range(6)]
for variable in angles if options.angle else comps:
The `angles if options.angle else comps` part evaluates to either `angles` or `comps` depending on the value of `options.angle`. It's sometimes called a "ternary operator" because it operates on three values (the condition and two possible results). If you're familiar with C or Java, it's similar to `options.angle ? angles : comps` (don't worry if you're not familiar with C/Java; just though that might help explain if you do happen to be).
The `for` loop then iterates over whichever of `angles` or `comps` is the result. With parentheses to clarify, it's equivalent to:
```
for variable in (angles if options.angle else comps):
```
Or similar to doing:
```
values = angles if options.angle else comps
for variable in values:
```
Personally, if I were going to use a loop like this, I'd probably write it in one or other of those two forms so that it's clearer what it does for someone reading it. Stephan noted that it at least needs the parentheses to work in a list comprehension which is probably because, in comprehensions, `if` is used (without an `else`) to select which items yielded by `for` are to be included.
if options.angle:
angle = variable
else:
X_C = variable * -X_L
As far as I can see, depending on `options.angle`, either `angle` or `X_C` is not defined. Unless they're each set to an initial/default value somewhere earlier, the next line is bound to fail.
junk = sys.stdout.write( "%4.2f %4.3f\n" % (angle,X_C) )
Is there a reason not to just use `print("%4.2f %4.3f" % (angle,X_C))? Unless `junk` is actually used later, you shouldn't need to assign the return value to anything.
"Michael F. Stemper" <michael.stemper@gmail.com> wrote or quoted:
for variable in angles if options.angle else comps:
, is fine, but I think what would be a bit clearer might be,
variables = angles if options.angle else comps
for variable in variables:
| Sysop: | DaiTengu |
|---|---|
| Location: | Appleton, WI |
| Users: | 1,116 |
| Nodes: | 10 (0 / 10) |
| Uptime: | 291:30:01 |
| Calls: | 14,323 |
| Calls today: | 1 |
| Files: | 186,347 |
| D/L today: |
10,929 files (3,250M bytes) |
| Messages: | 2,528,960 |