2

I am working on a function that usually returns 1 value, but sometimes returns 2 for similar reasons to this post, and noticed some unexpected behavior best illustrated by this example:

def testfcn1(return_two=False):
    a = 10
    return a, a*2 if return_two else a

def testfcn2(return_two=False):
    a = 10
    if return_two:
        return a, a*2
    return a

I would expect both functions to behave the same way. testfcn2 works as expected:

testfcn2(False)
10

testfcn2(True)
(10, 20)

However, testfcn1 always returns two values, and just returns the first value twice if return_two is False:

testfcn1(False)
(10, 10)

testfcn1(True)
(10, 20)

Is there a rationale for this kind of behavior?

1
  • 3
    But do you really want a function that sometimes returns an int & sometimes returns a tuple? That can get messy. If the number of values to be returned can vary, then always return a tuple & let the caller call the tuple's len method. A possible exception to this pattern is returning None instead of a tuple, but even then you can return an empty tuple. Commented Sep 18, 2015 at 14:58

2 Answers 2

5

In your testfcn1 , the expressions are grouped as -

(a, (a*2 if return_two else a))           #This would always return a tuple of 2 values.

And not (what you thought it would be) -

(a, a*2) if return_two else a             #This can return a tuple if return_two is True otherwise a single value `a` .

If you wanted the second grouping of expressions, you have to use brackets as I have used above.


Example to show the difference -

>>> 10, 20 if True else 10
(10, 20)
>>> 10, 20 if False else 10
(10, 10)
>>>
>>>
>>> (10, 20) if False else 10
10
>>> (10, 20) if True else 10
(10, 20)
>>>
>>>
>>> 10, (20 if False else 10)
(10, 10)
>>> 10, (20 if True else 10)
(10, 20)
Sign up to request clarification or add additional context in comments.

Comments

3

It a simple issue of operator precedence. return a, a*2 if return_two else a if interpreted as return a, (a*2 if return_two else a). You should use parenthesis in order to change precedence.

def testfcn1(return_two=False):
    a = 10
    return (a, a*2) if return_two else a

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.