3

I have a situation where I am going to have a lot of lists and the values in each of those lists need to be in some set of valid values. However the set of valid values is going to be different for each list. So before doing any appending to these lists I have to check for membership and that is making for a lot of repeated code. I'm finding myself tempted to extend the list object so that I wont have to do that membership check over and over.

class Attribute(list):
    def __init__(self,validList):
        self.valid = validList

    def append(self,inString):
        if inString not in self.valid:
            raise Exception, '%s is not a valid value for this attribute' % inString
        if inString not in self:
            super(Attribute,self).append(inString)

That way I could have each of my lists with a different valid set of values. However, I feel like extending the built-in objects is not often a good idea and I have avoided it in the past. So my questions are

  1. Is there a built-in way to do this or is there a library that has something like this already?
  2. Is this a bad idea? What issues might arise from doing something like this?

Overriding append method after inheriting from a Python List was helpful in making this code work.

Community
  • 1
  • 1
Kevin Thompson
  • 2,466
  • 4
  • 29
  • 40
  • 1
    Why not just wrap the list in your custom collection class? Then you don't have to worry about implementing all other list methods correctly. – rkrzr Jul 03 '13 at 16:42

1 Answers1

2

I guess you could go either way, but generally I avoid subclassing list. I might create my own collection object rather than subclassing, for example.

In your case, I would just filter each list to check for membership. Unless you're dealing with huge recordsets, it's probably not an issue.

list.append(1)
list.append(2)
list.append(3)
# list = [1, 2, 3]

valid_values = (2, 3)

list = [item for item in list if item in valid_values]
# list = [2, 3] now

As for your question about why append isn't working, it's because you're trying to append a list, rather than a list item. You can fix this by making it list.append(inString). If at some point you wanted to actually combine lists together, you can use list.extend(other_list) or list + other_list.

On a side note, most people in Python follow PEP-8 syntax for readability. That means inString would be named in_string.

Jordan
  • 31,971
  • 6
  • 56
  • 67
  • If `valid_values` is more than a few elements, you may want to use `frozen_set` instead of a tuple (or list), as it will permit faster item checking. – Jon Stewart Jul 03 '13 at 17:50
  • As a word of warning though, you'd really have to have a lot of elements or this be a performance-crucial piece of code for that to matter much, if at all. And frozensets take up more memory, so that's the tradeoff. – Jordan Jul 03 '13 at 17:56