内循环如何在每次迭代中附加?

时间:2017-07-06 01:04:15

标签: python function loops recursion nested

def per1(seq):
    if not seq:
        return [seq]
    else:
        res=[]
        for i in range(len(seq)):
            rest=seq[:i]+seq[i+1:]
            for x in per1(rest):
                 res.append(seq[i:i+1]+x)

        return res

print(per1('abc'))

该函数是打印一个置换的序列列表,但我不确定内部for循环是如何工作的。我曾尝试使用trace()来查看控件是如何通过循环移动的,但我无法确定循环第二次如何工作。第一次,' rest '值为'bc','c'

1 个答案:

答案 0 :(得分:0)

每次通过for i循环时,rest都会设置为输入字符串,并删除一个字符。第一次删除第一个字符时,第二次删除第二个字符,等等seq[:i]i之前的每个字符,而seq[i+1:]是{{1}之后的每个字符}}

然后它在i上递归调用自己。这将返回该较短字符串的所有排列。因此,当restrest时,会返回"bc"["bc", "cb"]循环遍历此列表,并将每个链接连接到for x(创建seq[i:i+1]时删除的字符),并将其附加到rest。< / p>

因此,主循环的第一次迭代将res设置为rest,然后将"bc""abc"追加到"acb"

第二次迭代做同样的事情,res设置为rest"ac"是缺失字符seq[i:i+1],因此它附加"b""bac""bca"

第三次迭代类似,res设置为rest,因此它将"ab""cab"追加到"cba"

特殊情况是递归的基本情况。如果输入字符串为空,我们只返回一个带有该空字符串的列表 - 空字符串具有简单的排列。当调用者执行其res循环时,它将简单地将此空字符串连接到当前字母上。需要这种情况来防止无限递归。您也可以将for x作为基本情况,因为单个字母的排列也很简单。