如何创建一个 returns 列表的递归函数,而不会超过二维? (Python)
How can I create a recursive function that returns a list without it becoming more than two dimension? (Python)
我正在关注 YouTube 上的 this 教程。我正在尝试创建一个函数,它接受两个输入,一个目标词和一组词,以及 returns 一个二维数组,其中包含词库中所有可能的组合以到达目标词。
例如,canConstruct("abc", ["ab", "c", "abc", "d"])
应该return[["ab","c"],["abc"]]
我的代码有很多缺陷,但我现在关注的主要问题是让最终输出成为一个二维列表。
我已经尝试 return 以多种方式返回列表。我认为 returning *list
可能会工作,因为当我打印出 str(*list)
时似乎删除了额外的 []
但我不能 return 这个。
相关代码如下:
result = []
def allConstruct(target, wordBank, memo = {}):
if target == "":
return([[]])
if target in memo:
return memo[target]
for word in wordBank:
...
# if match never gets set to False, that means word is a subset of target
if match == True:
#remove word from beginning of target
new_target = target[word_len:]
suffix_ways = allConstruct(new_target, wordBank)
for way in suffix_ways:
print("inserting word: " + word + " at start of list: " + str(way))
way.insert(0, word)
print("The result is " + str(way))
result.append(suffix_ways)
memo[target] = result
memo[target] = result
return result
我已经使我的测试用例变得超级简单,这样我就可以更好地理解错误检查打印语句。下面是我传递给函数的内容:
result = allConstruct("ab", ["ab", "a"])
print(result)
输出是这样的:
inserting word: ab at start of list: []
The result is ['ab']
inserting word: a at start of list: [['ab']]
The result is ['a', ['ab']]
[['a', ['ab']], [...]]
除了“aab”不是目标词这一明显问题外,我的 returning 列表是 ['a',['ab']]
,而它应该是 [['a', 'ab']]
。
我认为问题可能出在 way.insert(0, word)
,但我真的不太确定,因为我把自己弄糊涂了。
任何关于如何在递归函数中传回列表以免它变得一团糟的建议,我们将不胜感激!
存在这些问题:
result
不应该是一个全局变量,因为你从递归调用中得到一个结果,然后将它合并回 result
。这将导致重复信息。此外,当 result
是全局的时,你有一个有副作用的函数,调用者应该在想要进行新调用时重置 result
。这是不好的做法。
而是让 result
成为一个 local 名称,它在函数开始时设置为 []
,并返回给调用者。
您不想 append
递归调用的结果,因为该结果与您的结果具有 相同 二维结构建造。所以你需要使用 extend
来代替。
不是你的问题,但是 memo = {}
作为默认值参数是个坏主意。而是让默认值为 None
,并在函数体内分配空字典。否则该函数的下一次调用将继续使用先前填充的备忘录,这是不希望的。
这里更正:
def allConstruct(target, wordBank, memo = None):
if not memo:
memo = {} # Initialise for *every* toplevel call
result = [] # Local!
if target == "":
return [[]]
if target in memo:
return memo[target]
for word in wordBank:
word_len = len(word)
match = target.startswith(word)
# if match never gets set to False, that means word is a subset of target
if match == True:
# Remove word from beginning of target
new_target = target[word_len:]
suffix_ways = allConstruct(new_target, wordBank)
for way in suffix_ways:
print("inserting word: " + word + " at start of list: " + str(way))
way.insert(0, word)
print("The result is " + str(way))
result.extend(suffix_ways) # Extend!
memo[target] = result
memo[target] = result
return result
def allConstruct(target, wordBank):
new_res=[]
result = [] # Local!
memo=None
if not memo:
memo = {} # Initialise for *every* toplevel call
if target == "":
return [[]]
if target in memo:
return memo[target]
for word in wordBank:
word_len = len(word)
match = target.startswith(word)
# if match never gets set to False, that means word is a subset of target
if match == True:
# Remove word from beginning of target
new_target = target[word_len:]
suffix_ways = allConstruct(new_target, wordBank)
for way in suffix_ways:
print("inserting word: " + word + " at start of list: " + str(way))
way.insert(0, word)
print("The result is " + str(way))
new_res.append(way)
print(new_res)
return new_res
我正在关注 YouTube 上的 this 教程。我正在尝试创建一个函数,它接受两个输入,一个目标词和一组词,以及 returns 一个二维数组,其中包含词库中所有可能的组合以到达目标词。
例如,canConstruct("abc", ["ab", "c", "abc", "d"])
应该return[["ab","c"],["abc"]]
我的代码有很多缺陷,但我现在关注的主要问题是让最终输出成为一个二维列表。
我已经尝试 return 以多种方式返回列表。我认为 returning *list
可能会工作,因为当我打印出 str(*list)
时似乎删除了额外的 []
但我不能 return 这个。
相关代码如下:
result = []
def allConstruct(target, wordBank, memo = {}):
if target == "":
return([[]])
if target in memo:
return memo[target]
for word in wordBank:
...
# if match never gets set to False, that means word is a subset of target
if match == True:
#remove word from beginning of target
new_target = target[word_len:]
suffix_ways = allConstruct(new_target, wordBank)
for way in suffix_ways:
print("inserting word: " + word + " at start of list: " + str(way))
way.insert(0, word)
print("The result is " + str(way))
result.append(suffix_ways)
memo[target] = result
memo[target] = result
return result
我已经使我的测试用例变得超级简单,这样我就可以更好地理解错误检查打印语句。下面是我传递给函数的内容:
result = allConstruct("ab", ["ab", "a"])
print(result)
输出是这样的:
inserting word: ab at start of list: []
The result is ['ab']
inserting word: a at start of list: [['ab']]
The result is ['a', ['ab']]
[['a', ['ab']], [...]]
除了“aab”不是目标词这一明显问题外,我的 returning 列表是 ['a',['ab']]
,而它应该是 [['a', 'ab']]
。
我认为问题可能出在 way.insert(0, word)
,但我真的不太确定,因为我把自己弄糊涂了。
任何关于如何在递归函数中传回列表以免它变得一团糟的建议,我们将不胜感激!
存在这些问题:
result
不应该是一个全局变量,因为你从递归调用中得到一个结果,然后将它合并回result
。这将导致重复信息。此外,当result
是全局的时,你有一个有副作用的函数,调用者应该在想要进行新调用时重置result
。这是不好的做法。而是让
result
成为一个 local 名称,它在函数开始时设置为[]
,并返回给调用者。您不想
append
递归调用的结果,因为该结果与您的结果具有 相同 二维结构建造。所以你需要使用extend
来代替。不是你的问题,但是
memo = {}
作为默认值参数是个坏主意。而是让默认值为None
,并在函数体内分配空字典。否则该函数的下一次调用将继续使用先前填充的备忘录,这是不希望的。
这里更正:
def allConstruct(target, wordBank, memo = None):
if not memo:
memo = {} # Initialise for *every* toplevel call
result = [] # Local!
if target == "":
return [[]]
if target in memo:
return memo[target]
for word in wordBank:
word_len = len(word)
match = target.startswith(word)
# if match never gets set to False, that means word is a subset of target
if match == True:
# Remove word from beginning of target
new_target = target[word_len:]
suffix_ways = allConstruct(new_target, wordBank)
for way in suffix_ways:
print("inserting word: " + word + " at start of list: " + str(way))
way.insert(0, word)
print("The result is " + str(way))
result.extend(suffix_ways) # Extend!
memo[target] = result
memo[target] = result
return result
def allConstruct(target, wordBank):
new_res=[]
result = [] # Local!
memo=None
if not memo:
memo = {} # Initialise for *every* toplevel call
if target == "":
return [[]]
if target in memo:
return memo[target]
for word in wordBank:
word_len = len(word)
match = target.startswith(word)
# if match never gets set to False, that means word is a subset of target
if match == True:
# Remove word from beginning of target
new_target = target[word_len:]
suffix_ways = allConstruct(new_target, wordBank)
for way in suffix_ways:
print("inserting word: " + word + " at start of list: " + str(way))
way.insert(0, word)
print("The result is " + str(way))
new_res.append(way)
print(new_res)
return new_res