[Tutor] Functions returning multiple values
Steven D'Aprano
steve at pearwood.info
Sun Feb 21 17:46:41 CET 2010
On Mon, 22 Feb 2010 03:00:32 am Giorgio wrote:
> Hi,
>
> do you know if there is a way so that i can get multiple values from
> a function?
>
> For example:
>
> def count(a,b):
> c = a + b
> d = a - b
>
> How can I return the value of C and D?
Return a tuple of c and d:
>>> def count(a, b):
... c = a + b
... d = a - b
... return c, d
...
>>> t = count(15, 11)
>>> t
(26, 4)
You can also unpack the tuple immediately:
>>> x, y = count(15, 11)
>>> x
26
>>> y
4
> Then, i have another question: i've read, some time ago, this guide
> http://hetland.org/writing/instant-python.html, skipping the
> object-related part. Now i've started reading it, and have found
> something strange: just go where it says "Of course, now you know
> there is a better way. And why don’t we give it the default value of
> [] in the first place? Because of the way Python works, this would
> give all the Baskets the same empty list as default contents.". Can
> you please help me understanding this part?
When you declare a default value in a function like this:
def f(a, b, c=SOMETHING):
the expression SOMETHING is calculated once, when the function is
defined, and *not* each time you call the function.
So if I do this:
x = 1
y = 2
def f(a, b, c=x+y):
return a+b+c
the default value for c is calculated once, and stored inside the
function:
>>> f(0, 0)
3
Even if I change x or y:
>>> x = 9999
>>> f(0, 0)
3
So if I use a list as a default value (or a dict), the default is
calculated once and stored in the function. You can see it by looking
at the function's defaults:
>>> def f(alist=[]):
... alist.append(1)
... return alist
>>>
>>> f.func_defaults[0]
[]
Now, call the function without an argument:
>>> f()
[1]
>>> f()
[1, 1]
>>> f()
[1, 1, 1]
>>> f.func_defaults[0]
[1, 1, 1]
How is this happening? Because every time you call the function, it
appends 1 to the argument. If you don't supply an argument, it appends
1 to the default, changing it in place.
Why doesn't the same thing happen here?
>>> def g(x=0):
... x += 1
... return x
...
>>> g.func_defaults[0]
0
>>> g()
1
>>> g()
1
>>> g.func_defaults[0]
0
The answer is that ints are immutable: you can't change their value.
When you do x+=1, it doesn't modify the int 0 in place, turning it into
1. It leaves 0 as zero, and gives you a new int equal to one. So the
default value stored in the function never changes.
The difference boils down to immutable objects, which can't be changed
in place, and mutable objects, which can.
Immutable:
ints, floats, strings, tuples, frozensets
Mutable:
lists, dicts, sets, most custom classes
--
Steven D'Aprano
More information about the Tutor
mailing list