在 Python 中使用引用传递递归枚举

Enumerating recursively with pass by reference in Python

提问人:SS' 提问时间:8/22/2018 更新时间:8/22/2018 访问量:93

问:

所以这是一个面试问题的答案,列举所有可能的助记符(给定电话号码的可能字符序列)。类似于生成可能的排列问题和类似的东西,所以问题也适用于那里。

MAPPING = ('0', '1', 'ABC', 'DEF', 'GHI', 'JKL', 'MNO', 'PQRS', 'TUV', 'WXYZ')


def phone_mnemonic(phone_number):
    def phone_mnemonic_helper(digit):
        if digit == len(phone_number):
            # All digits are processed, so add partial_mnemonic to mnemonics.
            # (We add a copy since subsequent calls modify partial_mnemonic.)
            mnemonics.append(''.join(partial_mnemonic))
        else:
            # Try all possible characters for this digit.
            for c in MAPPING[int(phone_number[digit])]:
                partial_mnemonic[digit] = c
                phone_mnemonic_helper(digit + 1)

    mnemonics, partial_mnemonic = [], [0] * len(phone_number)
    phone_mnemonic_helper(0)
    return mnemonics

我对这在传递值/引用方面的工作原理感到更加困惑。由于“partial_mnemonic”是在调用帮助程序函数之前在底部声明的,并且在递归堆栈中被修改,因此它们不是在同一个“partial_mnemonic”对象上操作吗?

因为我们没有传入一个名为“partial_mnemonic”的列表,而只是使用外部作用域中的列表,为什么我们在修改同一个列表时没有遇到问题?

我想我可能对 Python 在按值/引用传递方面的工作方式有点困惑,但我不太确定为什么这段代码使用相同的“partial_mnemonic”列表工作,而不是实例化一个新的列表并在递归调用时传入。

Python 列表 递归 传递

评论

0赞 user2357112 8/22/2018
递归调用确实都在修改同一个列表。为什么这会是个问题?

答:

1赞 J. Blackadar 8/22/2018 #1

在输入递归函数之前,您正在创建一个新变量以递归方式保存部分助记符。进入递归帮助程序函数后,代码通过更改 at 的值并在每个数字位置构建助记符,并递归调用以继续构建可能性。一旦递归跟踪达到电话号码的长度,基本情况会将其附加到您的排列列表中。该代码将使用循环遍历每个可能性,循环再次调用相同的方法,只是使用现在包含部分构建的助记符的列表。没有理由将新列表传递到帮助程序函数,因为这会消除递归功能。partial_mnemonicpartial_mnemonicdigitpartial_mnemonicforpartial_mnemonic