递归算法 - 使用' +'扩展vs创建新列表

时间:2016-08-02 18:42:25

标签: python algorithm recursion combinations

所以我在下面有一个递归函数,用字母表中的每个小写字母替换'_'个字符,直到这些可能的小写字母的所有组合都替换为'_'个字符。

简单示例

  

repl_underscores('__A')

     

>>>[a_A,b_A,c_A......aaA,abA,acA....zzA]

我有这个功能使用扩展来建立列表,如下面的评论所提到的,重复地修改相同的现有列表并完成工作。

为了练习,我想重新编写以在每次调用时构建一个新列表,并将该结果传递给连续的递归调用,目的是获得相同的结果。

它无法正常工作,我知道这与我在每次通话中建立新列表这一事实有关,但我认为,因为我在建立的版本上传递了每次递归调用我都会好,因为这些调用会被告知变化。

我很难找到它破坏的地方。我知道我可以通过修改相同的列表(通过可变的默认值,全局变量或扩展)来使它工作,但我想在每次递归时建立一个新的清单。

def repl_underscores(letters,res=None):
    if res is None: res = list()
    if '_' not in letters: return res
    repl = [letters.replace('_',letter,1) for letter in string.ascii_lowercase]
    res = res + repl #using += works, due to extending being a mutation (same list referenced at each call)
    for each in repl:
        repl_underscores(each,res) #trying to pass modified list to keep building up
    return res

print(repl_underscores('__DER'))

3 个答案:

答案 0 :(得分:1)

最好不要修改函数参数,而是使用返回值进行构建(更多功能样式)。稍微修改一下代码就可以按预期工作了。

导入字符串

ok

答案 1 :(得分:0)

recyclerView.setLayoutManager(new GridLayoutManager(context, number_of_columns));

这条线是问题所在,正如您似乎已经猜到的那样。每次在递归调用中,它都会分配一个新的本地列表,它不会保留对旧的列表的引用,因此调用者不会收到更改通知。

幸运的是,你的功能已经返回了列表,所以让我们抓住它:

res = res + repl #using += works, due to extending being a mutation (same list referenced at each call)

答案 2 :(得分:-1)

只使用没有递归的函数:

from itertools import combinations_with_replacement, chain

def repl_underscores(letters):
    result = []
    for chars in combinations_with_replacement(string.lowercase, letters.count('_')):
        chars = chain(chars,[''])
        result.append(''.join(a+next(chars) for a in letters.split('_')))
    return result