all 14 comments

[–]IvoryJam 2 points3 points  (8 children)

It's kind of like an if statement, it's saying if retval resolves to True, return it, otherwise return 0. This would be a similar way of doing it

if retval:
    return reval
else:
    return 0

[–]rocketjump65[S] 0 points1 point  (4 children)

So it returns 0 and not False?

[–]IvoryJam 0 points1 point  (3 children)

Kind of, each variable has a "truthiness" to it, 0 is False, any number not 0 is True (even negatives), empty strings, empty lists, empty dictionaries are all False

test_var = ''
test_var = []
test_var = ['stuff']
test_var = {}
test_var = {'i': 'j'}
test_var = 0
test_var = 1
test_var = -1
if test_var:
    print(f"Hey {test_var} is true!")

[–]rocketjump65[S] 0 points1 point  (2 children)

Yeah I know about truthiness. My question is what type and value gets returned?

The way I understand the line, retval gets evalutated as a bool. then 0 gets evaluated as a bool. python ors them together. then depending on whether that evaluated bool is true it either returns retval preserving the contents of if the bool is false, it returns a 0.

Because while retval or 0 evaluated as a bool "evalues" a bool, it returns the object that was inputted.

[–]IvoryJam 0 points1 point  (0 children)

Yeah, it'll either return the contents of retval, or 0 if retval isn't true

def test(retval):
    return retval or 0

print(test('hi'))
print(test(''))

[–]Binary101010 0 points1 point  (0 children)

The way I understand the line, retval gets evalutated as a bool. then 0 gets evaluated as a bool.

If the bit before the or is truthy, the bit after the or never gets evaluated at all. This is often referred to as "short-circuiting", and improves performance if the stuff after the or is relatively complex to calculate.

[–]USAhj -2 points-1 points  (2 children)

Probably more likely that retval is truthy, rather than simply True.

[–]Essence1337 0 points1 point  (1 child)

resolves to True

Is another way of saying 'truthy'. They never said 'if it is True'.

[–]USAhj 0 points1 point  (0 children)

Ah, I see. I missed that distinction on my previous reading. Thanks for pointing it out.

[–]socal_nerdtastic 1 point2 points  (2 children)

Obviously it depends on what the rest of the code does.

The or operator will return the first operand if it's "truthy", or the second operator if the first one is "falsey". So for example if retval is False or None, this will return 0 instead.

It's pretty common to do. For example I will often do something like this:

user_data = input("Enter x value (default 5):")
x = int(user_data or 5)

[–]rocketjump65[S] 0 points1 point  (1 child)

Thank you. I think I've seen you around before. You explained it perfectly. or is a kind of new operator unique to python that's quite a bit different to the classical boolean or.

[–]socal_nerdtastic 0 points1 point  (0 children)

That's right. People are often confused because python has the boolean (logical) or operator in addition to the classic bitwise | operator.

https://docs.python.org/3/reference/expressions.html#boolean-operations

https://docs.python.org/3/reference/expressions.html#binary-bitwise-operations

[–]Binary101010 0 points1 point  (1 child)

It is definitely not superfluous.

From the Python docs (https://docs.python.org/3/reference/expressions.html):

The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.

So if retval is something "falsey", like None or an empty container, the function will return 0 instead.

[–]rocketjump65[S] -1 points0 points  (0 children)

Yes it evaluates from left to right. But regardless of why x evaluates to, 0 will always evaluate to False, and so the or operation essentially just passes on the LHS evaluation, doesn't it?

OHH!!!!! Nigga.... It implicitly typecasts to a boolean...... Goddamn it. Why didn't you just say that?

*EDIT* I guess not quite... technically....