简体   繁体   中英

Function with empty list as default argument gives different outputs on each call

I wrote a Python function to reverse a nested list:

def ReverseList(inputlist,parent=[]):
    
    if len(inputlist)==0:
        tem_out=parent[:]
        return tem_out
    
    else:
        next_i=inputlist[-1]
        
        if type(next_i) == list:
            parent.append(ReverseList(next_i,[]))
        else:
            parent.append(next_i)
            
        temp_par=parent[:]
        return ReverseList(inputlist[:-1],temp_par)

        
print(ReverseList([1,2,[11,22],3,5]))
print(ReverseList([1,2,[11,22],3,5]))
print(ReverseList([1,2,[11,22],3,5]))
print(ReverseList([1,2,[11,22],3,5]))

In the last 4 lines I repetitively called the same function with the same input. It gives following output:

[5, 3, [22, 11], 2, 1]
[5, 5, 3, [22, 11], 2, 1]
[5, 5, 5, 3, [22, 11], 2, 1]
[5, 5, 5, 5, 3, [22, 11], 2, 1]

Only in the first output shows the correct answer.

And I tried to do this without using default arguments, which gives the correct answer

def ReverseList_no_default_arg(inputlist,parent):

    if len(inputlist)==0:
        tem_out=parent[:]
        return tem_out

    else:
        next_i=inputlist[-1]

        if type(next_i) == list:
            parent.append(ReverseList_no_default_arg(next_i,[]))
        else:
            parent.append(next_i)

        temp_par=parent[:]
        return ReverseList_no_default_arg(inputlist[:-1],temp_par)


print(ReverseList_no_default_arg([1,2,[11,22],3,5],[]))
print(ReverseList_no_default_arg([1,2,[11,22],3,5],[]))
print(ReverseList_no_default_arg([1,2,[11,22],3,5],[]))
print(ReverseList_no_default_arg([1,2,[11,22],3,5],[]))

Which gives this as output

[5, 3, [22, 11], 2, 1]
[5, 3, [22, 11], 2, 1]
[5, 3, [22, 11], 2, 1]
[5, 3, [22, 11], 2, 1]

What is the reason behind this difference?

The expression parent=[] in your argument list is considered a dangerous default , as it defaults to a container , so it's to be avoided for just the reason you discovered. Instead, we can initialize parent to None and test for that and make it an empty list as needed:

def reverseList(inputList, parent=None):

    if parent is None:
        parent = []

    if not inputList:
        return parent

    *head, tail = inputList

    if isinstance(tail, list):
        parent.append(reverseList(tail))
    else:
        parent.append(tail)

    return reverseList(head, parent)


if __name__ == '__main__':

    array = [1, 2, [11, 22], 3, 5]
    print(array)

    print(reverseList(array))
    print(reverseList(array))
    print(reverseList(array))
    print(reverseList(array))

    print(array)

Note also the use of some Python3 syntax and the preferred isinstance test.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM