在 Python 中通过引用传递递归枚举

Enumerating recursively with pass by reference in Python

所以这是一道面试题的答案,枚举所有可能的助记符(给定一个phone数字的可能的字符序列)。类似于生成可能的排列问题和此类问题,因此问题也适用于此。

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

关于路过value/reference,我更困惑的是它是如何工作的。由于 'partial_mnemonic' 是在调用辅助函数之前在底部声明的,并且在其中进行了修改,所以在递归堆栈中,它们不是在同一个 'partial_mnemonic' 对象上操作吗?

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

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

您正在创建一个新的 partial_mnemonic 变量来递归保存您的部分助记符,然后再进入递归函数。输入递归辅助函数后,代码会通过更改每个 digit 处的 partial_mnemonic 的值在每个数字位构建助记符,并递归调用以保持构建可能性。一旦 partial_mnemonic 的递归跟踪达到 phone 数字的长度,基本情况会将其附加到您的排列列表中。代码将 运行 使用 for 循环遍历每种可能性,它再次调用相同的方法,只是 partial_mnemonic 列表现在包含部分构建的助记符。没有理由将新列表传递给辅助函数,因为这会消除递归功能。