Search code examples
pythoncontrol-flow

Python list updaitng even when condition evaluates to False


Why is the longest_palindrome variable updated when the isPalindrome() function evaluates to False? The if/else condition is not behaving as I would expect.

def palindromeCutting(s):
    if s == "":
        return ""

    letters = list(s)

    while len(letters) > 0:
        tmp = []
        longest_palindrome = []
    
        for i in range(len(letters)):
            tmp.append(letters[i])

            if isPalindrome(tmp):
                print("updating longest with tmp")
                longest_palindrome = tmp
            print("longest_palindrome:",longest_palindrome)

        if len(longest_palindrome) > 1:
            l = len(longest_palindrome)
            letters = letters[l:]
        else:
            return "".join(letters)

def isPalindrome(arr):
    left, right = 0, len(arr) - 1

    while left <= right:
        if arr[left] != arr[right]:
            return False
        left += 1
        right -= 1

    return True

The output for this when run with s = "aaacodedoc" is:

longest_palindrome: ['a']
longest_palindrome: ['a', 'a']
longest_palindrome: ['a', 'a', 'a']
longest_palindrome: ['a', 'a', 'a', 'c']
longest_palindrome: ['a', 'a', 'a', 'c', 'o']
longest_palindrome: ['a', 'a', 'a', 'c', 'o', 'd']
longest_palindrome: ['a', 'a', 'a', 'c', 'o', 'd', 'e']
longest_palindrome: ['a', 'a', 'a', 'c', 'o', 'd', 'e', 'd']
longest_palindrome: ['a', 'a', 'a', 'c', 'o', 'd', 'e', 'd', 'o']
longest_palindrome: ['a', 'a', 'a', 'c', 'o', 'd', 'e', 'd', 'o', 'c']

Solution

  • The problem is that you are setting longest_palindrom to tmp. From that point on, tmp and longest_palindrom are pointing to the same object. Whenever tmp is modified, the modification is reflected on longest_palindrom, and vice-versa.

    To avoid that, you could instead set longest_palindrom to a copy of tmp, replacing the line

    longest_palindrom = tmp
    

    by

    longest_palindrom = tmp[:]
    

    which sets longest_palindrom to a new list containing the elements of tmp.

    If you want a more in-depth explanation of list aliasing, the answers to this question explain it very well.