tags:

views:

273

answers:

5

Hello!

How to write the exprission shorter:

return '%.0f' % float_var if float_var else float_var

or

if float_var:
    return formatted_string
else:
    return None

Thanks!

+10  A: 

The expression <value> if <condition> else <other_value> is pretty idiomatic already -- certainly more so than the other example, and is probably preferred whenever <value> is simple. This is Python's ternary operator, so if you were looking for something like <condition> ? <value> : <other_value>, that doesn't exist.

If computing <value> or <other_value> takes a few steps, use the longer if: ... else: ... alternative.

John Feminella
+1, beat me to it.
Anthony Forloney
assuming you're in 2.5 onward.
Gregg Lind
@Gregg: Hopefully that's the case -- otherwise you're using 2.4 or earlier, which means your version of Python is at least 6 years old!
John Feminella
Check out Centos5, and other server distros, John. There is still plenty of 2.4 in the wild, ugh!
Gregg Lind
rukeba
@rukeba: The only stupid question is the unasked one.
John Feminella
+1  A: 

If you are using are already using v if c else u you are already using the most readable and efficient ternary operator.

There are other ways but they suffer in readability.

msw
+2  A: 

I would use brackets to make the expression more readable:

return ('%.0f' % float_var) if float_var else float_var

When I first saw it I read it as

return '%.0f' % (float_var if float_var else float_var)

which would be silly. I had to try it out to make sure which way it worked.

BTW Your first example not equivalent to your second example

if float_var:
    return formatted_string
else:
    return None

This will always return either a formatted string or None. Your first example if you pass in anything that evaluates to False (False, 0, 0.0, "", [] etc) will return that unchanged, so your return type could be string, boolean, list, int, float etc. This is probably not what you want, especially if 0.0 is a legitimate value for float_var. I would change your code to:

return ('%.0f' % float_var) if isinstance(float_var, float) else None

alternatively:

try:
    return "%.0f" % float_var
except TypeError:
    return None

which will work for other integers (and longs) by converting them to float.

Dave Kirby
@Dave, mostly good, though with that final alternative note that `"%.0f" % False` would return `"0"`, which might be undesirable too.
Peter Hansen
@Peter - good point, I forgot about the automatic conversion of True/False to 1/0.
Dave Kirby
The typecheck for `float` is always a warning sign. If the two classes of expected values are numbers and `None`, it makes a lot more sense to check `is not None` than `isinstance(foo, float)`, since the former still allows the operation to be duck typed.
Mike Graham
+1  A: 
  • It is not clear what exactly you want to do.

    1. The most literal interpretation would have it work like this

      >>> float_var = 4.5
      >>> '%.0f' % float_var if float_var else float_var
      '5' # This is a string
      >>> float_var = 0.0
      >>> '%.0f' % float_var if float_var else float_var
      0.0 # This is a float
      

      which I am almost certain you did not want.

    2. I guess you are wanting to check for None with "if float_var"? If so, you always spell it "if foo is not None", not "if foo", the former being clearer and less bug-prone.

      If that is what you intended, I suggest you revise your model. Propagating errors by repeatedly returning None is a bad thing: it is ugly and bug-prone and non-idiomatic. Use exceptions instead.

  • Shorter is not always better. Your snippets are not painfully long or unwieldly. In fact, you will want to make them a little longer if you use them to avoid a potential bug.

    • Someone may suggest abusing the short-circuiting behavior of or for this. However, this makes code harder to read and doesn't allow you to specify between None and other false values, which often leads to bugs.
Mike Graham
A: 
float_var and "%.0f" % float_vav

Isn't it awesome?

DasIch
Nope:>>> f=0.0>>> x=f and "%f" % f>>> type(x)<type 'float'>>>> f=0.1>>> x=f and "%f" % f>>> type(x)<type 'str'>... If the value is 0.0, you get a float, otherwise a string.
Kevin Little