Search code examples
pythonpython-3.xregexpython-re

'SuperList' Object not deleting elements when a regex is present


I am trying to create a 'SuperList' class which is a list with a del_all() method. When I try to make it work with regexes, the del_all() method doesn't delete anything at all.

This is my current code:

import re

class SuperList(list):

    def __init__(self, seq):
        list.__init__(self, seq)
        self.seq = list(seq)

    def del_all(self, item="", regex=None):
        if item not in self.seq:
            if not regex:
                raise ValueError("item not in list")
            else:
                for i in range(len(self.seq)):
                    if re.match(re.compile(regex), self.seq[i]):
                        self.seq.remove(self.seq[i])
        else:
            if not regex:
                while item in self.seq:
                    self.seq.remove(item)
            else:
                for i in range(len(self.seq)):
                    if re.match(regex, self.seq[i]):
                        self.seq.remove(self.seq[i])


super_list = SuperList(["A", "b", "f", "Y"])
super_list.del_all(regex=re.compile("[A-Z]]"))
print(super_list.seq)

The expected output here is ["b", "f"]. But instead I get ["A", "b", "f", "Y"]. How can I fix my code?


Solution

  • This pattern [A-Z]] will not match any of the items in the list. It matches an uppercase char A-Z followed by an ]

    If you change the pattern to [a-z] to match a lowercase char, the code has a match.

    But, in this part of the code you are removing the item in the list that you are iterating which might give you an error:

    IndexError: list index out of range
    

    For this part of the code

    for i in range(len(self.seq)):
        if re.match(regex, self.seq[i]):
            self.seq.remove(self.seq[i])
    

    What you might do, is not unset the index, but filter the seq using a for comprehension instead;

    self.seq = [x for x in self.seq if re.match(regex, x)]
    

    Output

    ['b', 'f']
    

    Then you might also take that same approach for the last part of the code where you use remove