Reputation: 20064
So I'm doing a problem, and I use a recursive solution. For simplicity, let's say the problem is that I need to find all anagrams of a given string. (The problem is much complicated, but this is enough to illustrate what I'm doing).
I am using recursion to do this.
all_anagrams = []
def main():
...
...
get_anagrams() # calls a method that appends anagrams to list all_anagrams
print all_anagrams
and the method get_anagrams
is:
def get_anagrams(user_word, anagram, words, inventory):
'''
Finds all anagrams for the given user_word.
'''
if len(inventory) == 0:
all_anagrams.append(anagram)
else:
for choice in words:
if len(choice) <= len(inventory) and choice in inventory:
anagram.append(choice)
inventory.subtract(choice)
get_anagrams(user_word, anagram, words, inventory)
anagram.pop()
inventory.add(choice)
all_anagrams
is supposed to be a nested list, where each sub-list is composed of some words.
Now get_anagrams
should change the global value of all_anagrams
but it doesn't. In main
, it prints [[], [], [], [], [], []]
, but within the method it prints the correct list.
Consider this for example:
>>> a_list = []
>>> def change_list(some_list):
... some_list.append(1)
... some_list.append(2)
...
>>>
>>> change_list(a_list)
>>> a_list
[1, 2]
I've tried defining the list as a global
list, or passing the list as a parameter since any changes to list made by callee should be reflected in the caller too. But nothing worked.
Why is it so? How do I fix it?
Upvotes: 0
Views: 108
Reputation: 239573
The actual problem is with the append
and pop
. When you do
all_anagrams.append(anagram)
You are adding the reference to anagram
to all_anagrams
. But, when the recursion unwinds, you are popping the values from anagram
. Thats why empty lists are printed in main
. The immediate fix would be like this
if len(choice) <= len(inventory) and choice in inventory:
inventory.subtract(choice)
get_anagrams(user_word, anagram + [choice], words, inventory)
inventory.add(choice)
And as e-satis suggested, please avoid using global variables and pass all_anagrams
as one of the parameters.
Upvotes: 3