473,386 Members | 1,886 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Default function arguments behaving badly

Hi

I'm having some trouble with a function I've written in Python:

def myFunction(l1,l2,result=[]):
index=0
for i in l1:
result.append([])
if type(i)==list:
myFunction(i,l2,result[index])
else:
for j in l2:
result[index].append(i*j)
index+=1
return result

l1 and l2 are lists and the function multiplies every element of l1
with every element of l2. l1 is (possibly) multi-dimensional, and the
recursive bit is in there to cope with that. For example, if
l1=[[1,2],[3,4]] and l2=[5,6] the result is
[[[5,6],[10,12]],[[15,18],[20,40]]].

The problem is that it works if I run it once, but then on repeated
runs the value for 'result' doesn't seem to set itself to my default of
[], but instead uses the state it was in last time the function was
run.

I've had a problem like this in the past and ended up rewriting the
function as a class and using something like self.result, but I don't
really like this solution as the code becomes considerabley more
difficult to read (and I suspect less efficient). Also, I suppose I
could feed in an empty array every time but that doesn't provide a very
intuitive interface to the function.

Does anyone know what is going on here? Is there an easy solution?

Thanks for your help!

Aug 24 '05 #1
3 1140
jo************@gmail.com wrote:
Hi
hi
I'm having some trouble with a function I've written in Python:

def myFunction(l1,l2,result=[]):
index=0
for i in l1:
result.append([])
if type(i)==list:
myFunction(i,l2,result[index])
else:
for j in l2:
result[index].append(i*j)
index+=1
return result The problem is that it works if I run it once, but then on repeated
runs the value for 'result' doesn't seem to set itself to my default of
[], but instead uses the state it was in last time the function was
run. Does anyone know what is going on here? Is there an easy solution?


the list you provide as default parameter is evaluated once (at loading
time of the function). so each time you call the function, it uses the
same list that has been filled before... you do not have the problem
with say and int or a string as they are non mutable objects. however
lists are mutable objects so... modify your function as follow:

def myFunction(l1,l2,result=None):
if result is None:
result = []

hth

--
rafi

"Imagination is more important than knowledge."
(Albert Einstein)
Aug 24 '05 #2
jo************@gmail.com wrote:
I'm having some trouble with a function I've written in Python: def myFunction(l1,l2,result=[]): [snipped rest of function and explanation of what it does]
Does anyone know what is going on here? Is there an easy solution?


It shined out like a supernova. It has to do with mutability of certain
Python objects (e.g. dicts and lists) and the fact that Python binds the
default arguments only once. So, when your function is defined, python
binds the name "result" to the value []. Then, your function runs the
first time using that original binding. The second time, it still uses
the original binding which, because lists are mutable, still contains
the prior list. Etcetera.

The solution is to never assign mutable objects to default arguments.
Instead, assign to None, like:

def myFunction(l1, l2, result=None):
if result is None:
result = []

Others will certainly post links to the python docs that explain this.

--
Paul McNett
http://paulmcnett.com

Aug 24 '05 #3
That works perfectly - Thanks! I'm always getting tripped up by the
mutability of lists, I should really learn to look out for it more...

Aug 24 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

46
by: J.R. | last post by:
Hi folks, The python can only support passing value in function call (right?), I'm wondering how to effectively pass a large parameter, such as a large list or dictionary? It could achieved...
14
by: Edward Diener | last post by:
In the tutorial on functions there are sections on default arguments and keyword arguments, yet I don't see the syntactic difference between them. For default arguments the tutorial shows: def...
12
by: earl | last post by:
class temp { public: temp(); foo(char, char, char*); private: char matrix; }; temp::foo(char p, char o, char m = matrix )
4
by: aling | last post by:
What's the rule of default argument of function in C++? I found that the default argument of function could not necessary be a constant value. Is it true? Previously I thought that the default...
41
by: Telmo Costa | last post by:
Hi. I have the following code: -------------------------------------- function Tunnel() { //arguments(???); } function Sum() { var sum = 0; for (i=0; i<arguments.length; i++) sum +=...
21
by: Dmitry Anikin | last post by:
I mean, it's very convenient when default parameters can be in any position, like def a_func(x = 2, y = 1, z): ... (that defaults must go last is really a C++ quirk which is needed for overload...
2
by: Steven D'Aprano | last post by:
The timeit module is ideal for measuring small code snippets; I want to measure large function objects. Because the timeit module takes the code snippet argument as a string, it is quite handy...
15
by: dspfun | last post by:
Hi, Is it possible to print the function name of the calling function? For example, f1() and f2() both calls f3(), in f3() I would like to print the name of the function calling f3() which...
35
by: bukzor | last post by:
I've found some bizzare behavior when using mutable values (lists, dicts, etc) as the default argument of a function. I want to get the community's feedback on this. It's easiest to explain with...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.