Home > Software design >  IndexError when iterating a list for Palidrome problem
IndexError when iterating a list for Palidrome problem

Time:09-28

Below is my solution for checking whether a string is a valid palidrome. The problem requires the removal or all non-alphanumeric characters, and the conversion of uppercase letters into lowercase, before checking whether what remains is a valid palidrome. I tried to tackle the problem using the ASCII table and Python's built in functions of ord() and chr().

def isPalindrome(s: str) -> bool:
        lst = list(s)
        for i in range(len(lst)):
            if ((ord(lst[i]) <= 122) and (ord(lst[i]) >= 97)) or ((ord(lst[i]) >= 48) and (ord(lst[i]) <= 57)):
                continue
            elif ord(lst[i]) >= 65 and ord(lst[i]) <= 90:
                lst[i] = chr(ord(lst[i])   32)
            else:
                lst.pop(i)
                
        for i in range(len(lst)):
            if lst[i] != lst[len(lst)-1-i]:
                return False
        
        return True

However, the program gives an IndexError, stating that the list index is out of range for the line

if ((ord(lst[i]) <= 122) and (ord(lst[i]) >= 97)) or ((ord(lst[i]) >= 48) and (ord(lst[i]) <= 57)):

I don't see why this would be the case? I am iterating through the length of the list no?

CodePudding user response:

it's a common problem: it's due to pop. You are going to short your list after computed the size, that is bigger at the beginning. In the following solution, you are creating a new list based on the ordinals of the first one, removing special chars and making all letters lower before performing the check:

python
def remove_special(s: str) -> list:
        lst = list(s)
        copy = list()
        for i in range(len(lst)):
            if ((ord(lst[i]) <= 122) and (ord(lst[i]) >= 97)) or ((ord(lst[i]) >= 48) and (ord(lst[i]) <= 57)):
                copy.append(ord(lst[i]))
            elif ord(lst[i]) >= 65 and ord(lst[i]) <= 90:
                copy.append(ord(lst[i])   32)
            else:
                continue
        return copy


def isPalindrome(s: str) -> bool:
        lst = remove_special(s)                
        for i in range(len(lst)):
            if lst[i] != lst[len(lst)-1-i]:
                return False
        
        return True
  • Related