无法理解此函数中的关键逗号

2024-06-17 15:47:22 发布

您现在位置:Python中文网/ 问答频道 /正文

关于回溯法我有两个问题。所以我在研究一个可以以所有合法方式生成n括号的函数。你知道吗

def gen_par(p, left, right, parens=[]):
    if left:
        gen_par(p + '(', left - 1, right)
    if right > left:
        gen_par(p + ')', left, right - 1)
    if not right:
        parens += p,
    return parens


print(gen_par('', 2, 2))
# >>> ['(())', '()()']

我注意到有一行parens += p,,结尾的,正在做一些非常重要的事情,我不明白为什么。你知道吗

如果我把,去掉,我会得到这个:

print(gen_par('', 2, 2))
# >>> ['(', '(', ')', ')', '(', ')', '(', ')']

另外,我不明白为什么parens=[]必须写在参数中,如果我把它移到body中:

def gen_par(p, left, right):
    parens = []
    if left:
        gen_par(p + '(', left - 1, right)
    if right > left:
        gen_par(p + ')', left, right - 1)
    if not right:
        parens += p,
    return parens

这行不通。你知道吗

所以这两个问题是:

  1. ,的功能是什么
  2. 为什么parens需要在参数区域中?你知道吗

谢谢你


Tags: 函数right参数returnifdef方式not
2条回答

问题的第一部分已经回答了逗号是什么创建元组,而不是括号。关于警告,请看我的一个问题:Why do tuples need parantheses in list comprehension

问题的第二部分非常简单:在第二段代码中,您将parens视为局部变量,该变量在每次迭代中都会重置,函数在最后返回一个空列表。可以将其视为全局变量,以获得与第一个代码等效的结果,如下所示:

parens = []

def gen_par(p, left, right):
    global parens
    if left:
        gen_par(p + '(', left - 1, right)
    if right > left:
        gen_par(p + ')', left, right - 1)
    if not right:
        parens += p,
    return parens

print(gen_par('', 2, 2))
# Returns ['(())', '()()'] correctly.

与流行的观点相反,创建元组不需要括号:

>>> x = 1,
>>> type(x)
<type 'tuple'>

唯一需要圆括号的时候是消除元组构造逗号和其他逗号用法之间的歧义。例如,逗号也用来分隔函数的参数,在这样的参数列表中,后面的逗号是可选的,所以

>>> type(1,)   # Equivalent to type(1)
<type 'int'>

但是

>>> type((1,))  # or type((1,),)
<type 'tuple'>

至于第二个问题,不要使用可变的默认参数。相反,显式地传递必要的列表,这样经过修改的默认参数就不会干扰对gen_par的其他调用。你知道吗

def gen_par(p, left, right, parens):
    if left:
        parens = gen_par(p + '(', left - 1, right, parens)
    if right > left:
        parens = gen_par(p + ')', left, right - 1, parens)
    if not right:
        parens += p,
    return parens


print(gen_par('', 2, 2, []))

相关问题 更多 >