Reputation: 1
The task is to go through a list, compare it with a value and then return the amount of times the value occurred. The comparison works and when I find the matching value I want to save it in a list. Then I want to get the length of that list. The problem is that every time i call on the function again the list resets, how do I avoid that?
def count_occurences(values, value):
matched_values = []
if values:
if values[0] == value:
matched_values.append(values[0])
count_occurences(values[1:], value)
else:
count_occurences(values[1:], value)
else:
return 0
return len(matched_values)
count_occurences([1, "one", 2, "two", "two", 3, "three", "three", "three"], "two")
In this case the expected output would be: 2.
Upvotes: 0
Views: 1172
Reputation: 368
matched_values = []
def count_occurences(values, value, matched_values):
if values:
if values[0] == value:
matched_values.append(values[0])
count_occurences(values[1:], value, matched_values)
else:
count_occurences(values[1:], value, matched_values)
else:
return 0
return len(matched_values, matched_values)
count_occurences([1, "one", 2, "two", "two", 3, "three", "three", "three"], "two", matched_values)
The list was reset at every call of the recursive function count_occurences
because you recreated the list at the beginning of the function with this line: matched_values = []
. This creates a new variable matched_values
that points to a new location in memory and does not have access to what was found by the previous round.
Initializing this empty list before the function is called ensures that the same location in memory will be accessed every time the function runs. Every recursive call will operate on the same list, and you won't lose information.
Upvotes: 0
Reputation: 2136
You can solve your immediate problem by simply moving the matched_values
assignment outside of the function, as shown below.
matched_values = []
def count_occurences(values, value):
if values:
if values[0] == value:
matched_values.append(values[0])
count_occurences(values[1:], value)
else:
count_occurences(values[1:], value)
else:
return 0
return len(matched_values)
count_occurences([1, "one", 2, "two", "two", 3, "three", "three", "three"], "two")
However, this code really raises more questions than it answers. Presumably you are doing this as a learning exercise as you can easily do this without a special function or recursion. So bearing that in mind I'd ask you:
matched_values
? By definition it will just be the same entry repeatedly so it adds no information over just knowing the number of matchesWith those in mind, you might consider something like this which does away with the list and involves no mutation and no side effects.
def count_occurences(values, value):
if values:
if values[0] == value:
return 1 + count_occurences(values[1:], value)
else:
return count_occurences(values[1:], value)
else:
return 0
(which is essentially identical to the simplification suggested by Andrej Kesely above)
Upvotes: 1
Reputation: 195543
As @juanpa.arrivillaga stated in comments, you are initializing matched_values
to empty list each call, so you are returning nothing effectively.
The script can be simplified, for example:
def count_occurences(values, value):
if values:
return (values[0] == value) + count_occurences(values[1:], value)
return 0
n = count_occurences([1, "one", 2, "two", "two", 3, "three", "three", "three"], "two")
print(n)
Prints:
2
Upvotes: 1