递归函数返回的列表被截断,默认列表参数为空

2024-10-03 21:24:39 发布

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

我想找出一个数的所有素数因子。我尝试在不传递空列表作为参数的情况下执行此操作。你知道吗

我可以在没有空列表参数的情况下调用函数podz,但是结果不正确-这是第一个问题-为什么? 我在podzb函数中得到了正确的结果,但必须提供空列表参数。你知道吗

代码:

def podz(x, lista = ()):
    # xa = []
    lis = list(lista)
    # lis = list(lista) # czemu to psuje wynik? jak odpalić krok po kroku?
    # print(lis)
    for i in range(2, x + 1):
        # print(f'x: {x}')
        # print(f'i: {i}')
        # print(f'lis: {lis}')
        if x % i == 0:
            lis.append(i)
            # print(f'lis2: {lis}')
            podz(int(x / i), lis)
            break
    return(lis)

def podzb(x, lista = ()):
    # xa = []
    lis = lista
    # lis = list(lista) # czemu to psuje wynik? jak odpalić krok po kroku?
    # print(lis)
    for i in range(2, x + 1):
        # print(f'x: {x}')
        # print(f'i: {i}')
        # print(f'lis: {lis}')
        if x % i == 0:
            lis.append(i)
            # print(f'lis2: {lis}')
            podzb(int(x / i), lis)
            break
    return(lis)


a = podz(50, [])
print(f'a: {a}')
aa = podz(50)
print(f'aa: {aa}')

a2 = podzb(50, [])
print(f'a2: {a2}')
# aa = podzb(50)        #this causes: AttributeError: 'tuple' object has no attribute 'append'
# print(f'aa: {aa}')

Tags: a2列表参数def情况listaaprint
3条回答

产生AttributeError的原因是默认参数是空元组(),而不是空列表[]。现在,不使用空列表作为various reasons的默认参数是正确的,但是因为您想改变这个对象,所以确实需要一个列表。你知道吗

解决办法是做一些

def podzb(x, lista=None):
    if lista is None:
        lista = []
    ... # rest of function

当您这样做时:

lis = list(lista)

你复制你的名单。所以你不能修改它。你知道吗

podz,这里:

lis = list(lista)

您可以从lista的内容创建一个新列表。然后在这里进行递归调用时传递这个新列表:

   if x % i == 0:
        lis.append(i)
        # print(f'lis2: {lis}')
        podz(int(x / i), lis)

因此,在递归调用中,您再次创建一个新列表并附加到它,然后在递归调用返回时丢弃这个新列表,并且由于递归调用对第一个列表的副本起作用,因此第一个列表也不会更新。你知道吗

要使其工作,必须将递归调用的结果添加到第一个列表中:

   if x % i == 0:
        lis.append(i)
        # print(f'lis2: {lis}')
        lis.extend(podz(int(x / i), lis))

第二个版本(podzb)没有复制列表,因此所有递归调用都会更新同一个列表。你知道吗

相关问题 更多 >