2

If I want to return more that one variable from a function in Python I have been doing the following:

def foo():
    firstName = 'Bob'
    lastName = 'Jones'
    return [firstName, lastName]

Then if I wanted to find only the first name I would do this

[firstName, dummy] = foo()

However, say I initially had the function

def fooInitial():
    firstName = 'Bob'
    return firstName

and I called this from many parts of my code, if I wanted to add the lastName as another output the way I have been doing, I would have to change everywhere else in my code that was calling it.

Is there a way to do something similar to Matlab where calling a = foo() gives me the first name (not the first and last in a list) and [a,b]=foo() gives me the first and last?

2
  • 1
    No, there is no way to do that. Commented Aug 9, 2013 at 10:34
  • 2
    Add to your function argument with default value == False and if argument True return [firstName, lastName] and if False return firstName Commented Aug 9, 2013 at 10:34

3 Answers 3

6

No, there isn't. You are better of either changing all the code calling fooInitial(), or by adding a different method that returns the two parameters and have fooInitial() use that method:

def barInitial():
    first_name, last_name = 'Bob', 'Jones'
    return first_name, last_name

def fooInitial():
    return barInitial()[0]

Note that you can just return a tuple instead of a list too; tuples only require a comma to define so the syntax is lighter (no need for square brackets). You can do the same when unpacking the returned value:

first_name, last_name = barInitial()
Sign up to request clarification or add additional context in comments.

3 Comments

A namedtuple is probably not a bad idea - going on the returning multiple values part of the OP... (just can't be bothered to write an answer for it)
Yes, I like this. Changing the name of the initial function seems the best and easiest thing to do. Thanks!
@MartijnPieters I agree with all of your answer except for the first three words.
1

You could do this:

def foo(last=None):
    # current behaviour, change no code
    If not last:
        return 'bob'

    # new behaviour return first and last list
    return ['bob', 'jones']

The addition of the named keyword with a default argument gives you your current behaviour for code you don't want to change, and for new code where you want first and last returned you would use

first, last = foo(last=true)

Comments

0

It is possible, but I don't recommend it.

# WARNING: Breaks iteration over chars

class StrOrPair(str):
    def __new__(cls, name, lastname):
        return str.__new__(cls, name)

    def __init__(self, name, lastname):
        str.__init__(self, name)
        self.lastname = lastname

    # __iter__ is used for unpacking
    def __iter__(self):
        yield self
        yield self.lastname

def foo():
    return StrOrPair('Bob', 'Jones')

name = foo()
[first, second] = foo()

print(name) # Bob
print(first) # Bob
print(second) # Jones

# broken iteration over chars:
for c in name:
    print(c) # expect 'B', 'o', 'b' but get 'Bob', 'Jones'

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.