5

I have this code here:

import re
def get_attr(str, attr):
    m = re.search(attr + r'=(\w+)', str)
    return None if not m else m.group(1)

str = 'type=greeting hello=world'

print get_attr(str, 'type')   # greeting    
print get_attr(str, 'hello')  # world
print get_attr(str, 'attr')   # None

Which works, but I am not particularly fond of this line:

return None if not m else m.group(1)

In my opinion this would look cleaner if we could use a ternary operator:

return (m ? m.group(1) : None)

But that of course isn't there. What do you suggest?

NullUserException
  • 77,975
  • 25
  • 199
  • 226
  • 1
    `None if not m else m.group(1)` **is** the Python equivalent to `m ? m.group(1) : None`! –  Sep 29 '10 at 17:02
  • @delnan I know. It just doesn't strike as particularly readable to me; maybe I am too used to the "regular" ternary operator. That's why I am asking this question. – NullUserException Sep 29 '10 at 17:03
  • 5
    What makes `?` and `:` more readable than `if .. else` ? You can actually read that line out loud! – Jochen Ritzel Sep 29 '10 at 17:14
  • 1
    It seems like the only advantage in your preferred ternary syntax is order, so why not just use that order in python, i.e. return m.group(1) if m else None? Sure seems easier to follow to me than c-style ternary syntax. Perhaps you were thinking the first return value would get evaluated before the conditional? – Jeffrey Harris Sep 29 '10 at 18:33

4 Answers4

10

Python has a ternary operator. You're using it. It's just in the X if Y else Z form.

That said, I'm prone to writing these things out. Fitting things on one line isn't so great if you sacrifice clarity.

def get_attr(str, attr):
    m = re.search(attr + r'=(\w+)', str)
    if m:
        return m.group(1)

    return None
Chris B.
  • 71,470
  • 23
  • 89
  • 130
4

Another option is to use:

return m.group(1) if m else m

It's explicit, and you don't have to do any logic puzzles to understand it :)

unutbu
  • 711,858
  • 148
  • 1,594
  • 1,547
  • 4
    How is that more explicit than return None? Who knows what `m` is there? What if m is actually '' or 0 or some custom class that evaluates to False – Falmarri Sep 29 '10 at 19:01
3
return m and m.group(1)

would be one Pythonic way to do it.

If m is None (or something else that evaluates "falsely"), it returns m, but if m is "true-ish", then it returns m.group(1).

Mark Rushakoff
  • 224,642
  • 43
  • 388
  • 389
  • 4
    I feel like this is trying to be too hard to be clever. – Daenyth Sep 29 '10 at 17:00
  • Actually, if expressions have superseded the clever use of the fact that boolean operators return their operands. –  Sep 29 '10 at 17:01
  • 2
    Agreed. It works, but it kind of feels like an abuse of the `and` operator. Oddly, I don't feel the same way about the `or` operator (e.g. `return x or 'NO VALUE'`) – Chris B. Sep 29 '10 at 17:03
  • To me it looks much more "perlish" than pythonic. (i.e. too much idiomatic) – Boris Gorelik Nov 24 '11 at 17:42
2

What you have there is python's conditional operator. IMO it's perfectly pythonic as-is and needs no change. Remember, explicit is better than implicit. What you have now is readable and instantly understandable.

Daenyth
  • 31,276
  • 11
  • 75
  • 115