I am creating a new class in UserList, and trying to override the add, append, and extend methods so that duplicate values will not be added to the list by any of these operations. So far I have started with trying to override the append method and when I try to implement the class on an object I get the error: maximum recursion depth exceeded. Here's what I have so far:
from collections import UserList
class UList(UserList):
def append(self,item):
for s in self:
if item == s:
print ("Item already exists in list")
else:
self.append(item)
x = [1,2,3,4,5]
z = UList(x)
print (z)
z.append(1)
Well, think about it. You're already in self.append()
. And then you call self.append()
. This is a recursion and the next time through the code, nothing has changed (the item is still not in the list) so you recurse again and then again and then again and eventually, Python runs out of stack space to store the state of your recursion and you get the error.
Don't call self.append()
. You have to call the base class method, since yours can't do the append.
def append(self, item):
for s in self:
if item == s:
print ("Item already exists in list")
else:
UserList.append(self, item)
You can also use super()
for this but it's not strictly necessary in this case; super()
is vital in multiple-inheritance scenarios but in simpler situations, I find explicitly calling the base class is clearer.
Another point is that iterating over the whole list to see whether your item is in it is wasting time. Instead just do:
def append(self, item):
if item in self:
print("Item already exists in list")
else:
UserList.append(self, item)
You might also reconsider printing an error in your append()
method. It would be better to raise an exception so that the code that's using your class can detect the error and handle it as desired. You can also make the error message more descriptive so it says what duplicate item was found.
def append(self, item):
if item in self:
raise ValueError(repr(item) + " already exists in list")
else:
UserList.append(self, item)
You might also just consider using a set()
if you don't need to maintain the order. It doesn't store duplicates, so you can just add items and you will never get a duplicate; you don't have to check first.