2

I have a function like this in Python 3.4:

def is_value_valid(the_str):
    return len(the_str) != 0

There are of course other ways to write this, such as return the_str != "". Are there more pythonic ways of writing this expression? I am familiar with the concepts of truthy/falsy, so I know I could shortcut this in an if condition:

if not the_str:
    # do stuff

But the if expects a boolean result in its expression (this is my naive oversimplification here as a C++ programmer; I'm not familiar with standardese for this). However, there is nothing there to force the expression to evaluate to boolean in the return statement. I have tried just returning the string, and as long as no one treats the returned value as a string, it works just fine in calling code under boolean context. But from a post-condition perspective, I don't want to return a non-boolean type.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
void.pointer
  • 24,859
  • 31
  • 132
  • 243
  • 9
    `bool(the_str)`?? – Bhargav Rao Jan 12 '16 at 14:36
  • `if the_str:` would be the most Pythonic way to write it. It's not necessary to force the interpreter to cast the type. `if` does not _expect_ a boolean result in Python. In Python, `if` merely treats all results as boolean, whether they're boolean or not. – kojiro Jan 12 '16 at 14:41
  • FWIW, `'foo' or 'bar'` does not return a boolean either. You may have to relax your definition of a *truthy value* for Python. – deceze Jan 12 '16 at 14:42
  • Why not simply `if not bool(the_str)` ? – Burhan Khalid Jan 12 '16 at 14:44
  • 1
    @Burhan Why not simply `if not the_str`? – deceze Jan 12 '16 at 14:45
  • 1
    IMHO, the most Pythonic way would be to simply use the `if` statement. Why waste a function call for something so trivial? Unless, of course, this is just a simplified example. – PM 2Ring Jan 12 '16 at 14:45
  • 1
    I _truly_ do not understand the reasoning behind explicitly casting the value, and would appreciate clarification. (I gather that there's some attempt to explain it in the question, but I don't get it.) – kojiro Jan 12 '16 at 14:46
  • @PM2Ring: because you can't return `if` statement. `if the_str: return True`, `else: return False` is far more overkill. And there may be much more in the function, what if that string was produced by an external call? – Martijn Pieters Jan 12 '16 at 14:56
  • @MartijnPieters: Understood. If the real code is more complex than what's in the OP, then sure, it may make sense to wrap this in a function. But if the real code is simply testing if a string is empty or not, then I think it's better to have a simple explicit `if` rather than calling a function. – PM 2Ring Jan 12 '16 at 15:03
  • 2
    @PM2Ring: *I have tried just returning the string, and as long as no one treats the returned value as a string, it works just fine in calling code under boolean context. But from a post-condition perspective, I don't want to return a non-boolean type.*. So the intention is for the function to return a boolean. Returning a string instead exposes an implementation detail of the function and returns the wrong type. `bool()` is *the only proper solution* for this use-case. – Martijn Pieters Jan 12 '16 at 15:05
  • @MartijnPieters: Sure. _If_ the OP really needs a function for this, then `bool()` is the proper solution. I'm just questioning the need for the `is_value_valid` function in the first place. I guess a compromise would be to call `bool()` inline, rather than having it hidden inside `is_value_valid`. – PM 2Ring Jan 12 '16 at 15:11

5 Answers5

7

This is exactly what the bool() function does; return a boolean based on evaluating the truth value of the argument, just like an if statement would:

return bool(the_str)

Note that if doesn't expect a boolean value. It simply evaluates the truth value of the result of the expression.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • `return True if the_str else False`. I see the equivalent of this weird ternary idiom in PHP all the time. I just don't get why we're doing this exercise. :( – kojiro Jan 12 '16 at 14:47
  • 2
    @kojiro: if a function promises to return a boolean, it is better to actually return a boolean. That makes for a cleaner interface. – Martijn Pieters Jan 12 '16 at 14:48
  • Is that why? From the question, it sounds like the argument is that `if` _expects_ a boolean, not that a function promises it. – kojiro Jan 12 '16 at 14:49
  • @kojiro: That's the *post-condition perspective*; the post-condition is an expectation about what a function does. The post-condition here is that a boolean is returned. – Martijn Pieters Jan 12 '16 at 14:50
  • OK. I can accept this explanation, but I was definitely scratching my head at the level of effort for a while! – kojiro Jan 12 '16 at 14:51
  • @kojiro `return $foo ? true : false` is terrible in any language. In PHP that should be `return (bool)$foo`, if anything. – deceze Jan 12 '16 at 14:52
  • 3
    @kojiro: There are loads of antipatterns in wide use, waiting to become bugs. Like [this one](https://searchcode.com/?q=super%28type%28self%29+lang%3APython) or [this one](https://searchcode.com/?q=super%28self.__class__+lang%3APython), see [Why is Python 3.x's super() magic?](https://stackoverflow.com/a/19609168). There are a lot of programmers out that that *don't understand their craft*. – Martijn Pieters Jan 12 '16 at 15:07
1
>>> bool("foo")
True
>>> bool("")
False

Empty strings evaluate to False, but everything else evaluates to True. So this should not be used for any kind of parsing purposes.

So just return bool(the_str) in your case.

zangw
  • 43,869
  • 19
  • 177
  • 214
1

The if statement automatically evaluates a string as a boolean. However, if you want to return your string as a boolean you would simply do

return bool(the_str)
tkdkop
  • 119
  • 1
  • 6
0

bool(the_str) is definitely the way to go, as several have mentioned.

But if your method requires that a string be given, I would also test for the string actually being a string (because bool(5) and bool("this is a string") will both return true.

return isinstance(the_str, str) and bool(the_str)

Or when used in an if statement:

if isinstance(the_str, str) and the_str:
    # here we are sure it's a string whose length > 0
mjwunderlich
  • 1,025
  • 8
  • 13
  • 1
    In an `if` context, just use `isinstance(the_str, str) and the_str`; using `bool()` there is entirely redundant. – Martijn Pieters Jan 12 '16 at 14:49
  • 2
    This is not what the question is asking about though. They are asking how to produce a boolean to return from a function. It is not about validating that the value tested is a string, only how to produce a boolean for the truth value. – Martijn Pieters Jan 12 '16 at 14:52
  • I would argue it depends on context -- for some methods `return isinstance(the_str, str) and bool(the_str)` might be what's necessary – mjwunderlich Jan 12 '16 at 14:55
  • That would return `False` or the value of `the_str` again, so not always a boolean. – Martijn Pieters Jan 12 '16 at 14:57
-2
def is_value_valid(the_str):
    return bool(len(the_str) != 0)

Using bool(x) converts the value to a boolean. This function takes len(the_str) != 0, evaluates it, converts it to bool, then returns the value.

The bool(x) is not required, you can just have the parentheses, because it will already return a bool, as evaluations return boolean by default.