Reputation: 8293
Any way to write this in one line in Python, or even better, as an expression instead of a statement?
parts = ['0', '1', 'None', '5', '4']
[int(p) for p in parts]
This of course gives an error,
ValueError: invalid literal for int() with base 10: 'None'
So:
[p=='None' and None or int(p) for p in parts]
Doesn't work because you can't use None
with the and/or construct reliably. (Even if p=='None'
is true, None
is equivalent to false so it goes to the or
part.)
[int(p) if p=='None' else None for p in parts]
Also doesn't work. I guess it evaluates int(p)
before the conditions? (Seems odd semantics.)
a = []
for p in parts:
if p=='None': k = None; else: k = int(p)
a.append(k)
Nope, invalid syntax.
a = []
for p in parts:
if p=='None':
k = None;
else:
k = int(p)
a.append(k)
Ah! Finally. But isn't there a shorter way to write such a simple loop?
Upvotes: 0
Views: 22856
Reputation: 4260
A simpler solution will be:
parts = ['0', '1', 'None', '5', '4']
[int(p) for p in parts if p.isdigit()]
However, float is not accepted here. If float string(?? I dont know what to call that) to integer is a necessity, you can consider the following:
parts = ['0', '1', 'None', '5', '4']
[int(p.split(".")[0]) for p in parts if p.replace(".", "", 1).isdigit()]
Upvotes: 0
Reputation: 8257
Do you really only have 1 place in your code where you need this transform? If not, define a function and then make it multiple lines, commented, and easy to follow. That way you hide the complexity of your code, and keep the main code simple to read.
Upvotes: 0
Reputation: 822
[ [int, eval] [p=='None'] (p) for p in parts]
Should be save as eval is only called on string 'None'.
Upvotes: 4
Reputation: 17138
Almost had it:
[int(p) if p != 'None' else None for p in parts]
Upvotes: 7
Reputation: 602685
You almost got it right:
[None if p == 'None' else int(p) for p in parts]
Upvotes: 14