This question already has answers here:
"Least Astonishment" and the Mutable Default Argument
(33 answers)
Closed 2 years ago.
I'm doing some discrete mathematics stuff for a teacher, he asked me to try and do everything recursively. For some strange reason the list i'm using for a function is the same as it was the last time I called the function.
Here's my code:
def extended_euclidean_algorithm(a:int, b:int, equations=list()):
#This line is just for debugging and checking that my hipothesis was correct
print (len(equations))
if b==0:
return
if a<b:
b,a=a,b
quotient=a//b
remainder=a%b
equations.append(f"{a}={quotient}*{b}+{remainder}")
if extended_euclidean_algorithm(b, remainder, equations):
return equations
for i, equation in enumerate(equations):
equations[i]=equation.split('+')
equations[i][0]=equations[i][0].split('=')
equations[i][0]="-".join(equations[i][0])
equations[i]='='.join(equations[i])
return True
First time I call it, it's Ok. But second time I call it includes the numbers from the last time I called it.
Since you set the list in the arguments, by default the list exists and can be appended to.
You better use:
def extended_euclidean_algorithm(a:int, b:int, equations=None):
equations = equations if equations else []
In this way, equations - if not set - is None rather than an empty list.
Check out the pythontutor visualization here:
Related
This question already has answers here:
Why do these list operations (methods: clear / extend / reverse / append / sort / remove) return None, rather than the resulting list?
(6 answers)
Closed 3 months ago.
I am currently working in codecademy on a Python course and while trying to define a function that takes in a list and returns a list with the length of that same list added to the list I realized I keeping getting "None" instead of a full list and was wondering why.
I was able figure out the correct solution but for my own education, I'm curious why my original code didn't work as intended.
#This is the first one I tried
def append_size(lst):
return lst.append(len(lst))
#Uncomment the line below when your function is done
print(append_size([23, 42, 108]))
# returns None instead of [23, 42, 108]
#This is the correct function
def append_size(lst):
lst.append(len(lst))
return lst
lst.append always returns None. It modifies lst in place, so all you need to do is return lst itself.
def append_size(lst):
lst.append(len(lst))
return lst
This is a violation, though, of the usually conventional (followed by list.append itself) that a function or method should either modify an argument in-place and return None or return a new value based on the unchanged argument.
There's no particular need to return lst, since presumably the caller already has a reference to the list, as they were able to pass it as an argument in the first place.
This question already has answers here:
"Least Astonishment" and the Mutable Default Argument
(33 answers)
Why does PyCharm warn about mutable default arguments? How can I work around them?
(5 answers)
Closed 9 months ago.
I have the following code:
def my_function(x, l=[]):
for i in range(x):
l.append(i+i)
print(l)
my_function(2)
my_function(3)
For the first function call it prints [0,2] which is ok, but then for the second call it prints [0,2,0,2,4]!!! Why? I expected it to be only [0,2,4] since my second argument (or the absence of it) is an empty list. Am I doing something wrong? Am I assuming something wrong? Any help will be greatly appreciated.
It's printing that because the list object does not change between function calls. Try creating a new list object for each call like in the following modified code:
def my_function(x, l):
for i in range(x):
l.append(i+i)
print(l)
my_function(2, list())
my_function(3, list())
This question already has answers here:
Can a variable number of arguments be passed to a function?
(6 answers)
Closed 8 years ago.
How do you write a function in Python with variable arguments into the function and return variable number of outputs? Is this even possible with the constraints?
You mean like this. This is quite similar to ellipses in Java. When supplied with a variable amount of arguments, you can unpack these arguments as a list which you can manipulate as you deem necessary.
def func(*args):
print len(args) # num of vars
yes you can, take a look at splat operator
def my_function(*a): #here a will be list or tuple depend wt u passed
# do your stuff with a
**a for dictionary
This question already has answers here:
I need help wrapping my head around the return statement with Python and its role in this recursive statement
(2 answers)
Closed 8 years ago.
def fudz(n):
if n <= 2:
return 1
print("nom" * n)
return fudz(n-1) + fudz(n//2)
result = fudz(4)
Can someone give me a step by step of this function?
This is a recursive function, which means it calls an instance of itself on a simplified instance of the problem until it gets to a base case for which it already knows the answer. Remember that any call to a function occurs in its own stack frame, so it's going to have its own value for n.
You can walk through it yourself. First, think about what happens when n==2. Then think about n==3, and increase n until it makes sense to you.
This question already has answers here:
"Least Astonishment" and the Mutable Default Argument
(33 answers)
Closed 8 years ago.
def word_to_syllable(w,li=[]):
if not w:
return li
pattern = """
########
"""
pattern = re.sub("C","[^aeiou]",pattern)
pattern = re.sub("V","[aeiou]",pattern)
match = re.findall(pattern,w,re.VERBOSE)[0]
#print(li)
li.append(match)
w = w[len(match):]
return word_to_syllable(w,li)
This works okay for the first call, but then local variable li somehow doesn't get forgotten and new values are just appended to the old ones - instead of string, as name of the function suggests, being split to it's own list. Yeah, if I define my function without default argument and instead say it's empty list later in the call , everything's just fine, but I'm curious about what is exactly happening with this code above.
Using a list as a default argument in Python will produce surprising results because it's mutable, so (w,li=[]) isn't what you want.
See here: "Least Astonishment" and the Mutable Default Argument
and here: http://www.deadlybloodyserious.com/2008/05/default-argument-blunders/
Short version is that default arguments are evaluated when the function is defined, not when the function is run like you'd expect.