0

Question

In python 2.7, I want to create a custom list that extends the python list by prefilling it with some static elements. I also want to extent the python list by adding some custom methods (i.e. filtering, re-initialization, etc...).

For example:

my_list = FitFuctionsList()

should give me a list already filled with some fixed elements.

I tried to inherit from the python list:

class FitFuctionsList(list):
    def __init__(self):
        list.__init__(['some', 'fixed', 'list'])

but the initialization fails (an empty list is returned).

Suggestions on alternative approaches are also welcome.

Solution summary

nachshon provided a working solution even though he does not explain why it works (and why the previous example did not):

class FitFuctionsList(list):
    def __init__(self):
        super(FitFuctionsList, self).__init__(['some', 'fixed', 'list'])

If the need is only to initialize a list with fixed values (no custom methods), Claudiu provided a clever way of using an helper function with an attribute to initialize the list. This methods is elegant and robust since it avoids using globals:

def FitFuctionsList():
    return list(FitFuctionsList.prefilled_elements)
FitFuctionsList.prefilled_elements = ["a", "b", "rofl"]
Community
  • 1
  • 1
user2304916
  • 7,882
  • 5
  • 39
  • 53
  • 3
    Asking for a solution is the wrong way of asking a question. Please edit your post to show what you have tried so far. – fvrghl Sep 23 '13 at 22:05
  • Check this question: http://stackoverflow.com/questions/9432719/python-how-can-i-inherit-from-the-built-in-list-type – dbf Sep 23 '13 at 22:06
  • what is wrong with `my_list=[static_element(i) for i in range(length)]`? – dawg Sep 23 '13 at 22:07
  • @fvrghi, I updated the question to address your point. – user2304916 Sep 23 '13 at 22:14
  • @drewk, see updated question: I want to be able to add custom methods. – user2304916 Sep 23 '13 at 22:15
  • 1
    Are you sure the list object is the appropriate place for this extra functionality? What's wrong with just writing module-level functions (or class-level, or whatever) to initialize and manipulate regular lists? [Do you really need inheritance, or is composition more appropriate?](http://stackoverflow.com/questions/3945940/what-to-consider-before-subclassing-list) – Henry Keiter Sep 23 '13 at 22:34
  • I further edited the question, I don't think is off-topic. It passes the question checklist IMHO. – user2304916 Sep 24 '13 at 23:20

3 Answers3

1

It seems the simplest solution here would be a helper function, something like...

prefilled_elements = ["a", "b", "rofl"]
def FitFuctionsList():
    return list(prefilled_elements)

EDIT: and you could do the following if you didn't want prefilled_elements to be a global:

def FitFuctionsList():
    return list(FitFuctionsList.prefilled_elements)
FitFuctionsList.prefilled_elements = ["a", "b", "rofl"]

But as to your updated question of having custom methods, you'll have to subclass list as nachson shows.

Community
  • 1
  • 1
Claudiu
  • 224,032
  • 165
  • 485
  • 680
  • I would like to inherit from the python `list` so that I can add more custom functionality. – user2304916 Sep 23 '13 at 22:20
  • @user2304916: ok, that wasn't in your initial question – Claudiu Sep 23 '13 at 22:46
  • I know, I added that bit of information a few minutes later, sorry. I posted the question specifically because I wanted to avoid globals and have a "fresh" initialization each time. If I have to use the global variable `prefilled_elements` there is no point in even using the helper function, I just use that variable. – user2304916 Sep 23 '13 at 23:14
  • @user2304916: if you want custom methods then you'll have to extend the `list` class. But if all you want is to hide the global, then that's possible, and this gives you a 'fresh' initialization each time (that is, it gives you a different list each time you call the function) – Claudiu Sep 24 '13 at 00:06
1

You can inherit from list like this:

class FitFunctionsList(list):

  def __init__(self, *args, **kwargs):
     super(FitFunctionsList, self).__init__(['some','default','values'])
  def my_custom_filter(self, criteria):
     pass`

that will initialize the list with default values, you can treat it as a list and you can add custom methods.

In response to @user2304916 comment on this answer:

list.__init__(self, ['some','default','values']) 

should work but super returns an object that will allow you to access all inherited stuff, in the case of multiple inheritence it will give you access to all metods in the correct order. it also does not require you specify which class that you inherit from you call a parent methos.

Shani
  • 418
  • 2
  • 8
  • This solution works. Can you please explain, however, why using `list.__init__(['some','default','values'])` doesn't and what the `super` call does exactly. Thanks – user2304916 Sep 23 '13 at 22:43
  • Would be good to keep the *args if provided, thus something like `super(FitFunctionsList, self).__init__(list(*args)+['some','default','values'])` – Thierry J. Sep 24 '13 at 00:18
  • list.__init__(self, ['some','default','values']) does not work for me. It returns an empty list! – user2304916 Sep 26 '13 at 19:23
  • @user2304916 The __init__ function does not return a list, it initializes self with the values you passed it. – Shani Sep 26 '13 at 20:39
0

You could do something along these lines:

class FitFunctionList(list):
    def __init__(self, **kwargs):
        if 'func' in kwargs:
            self.func=kwargs['func']
        else:
            self.func=range

        if 'args' in kwargs:
            self.args=kwargs['args']
        else:
            self.args=10

        super(FitFunctionList, self).__init__(self.func(self.args))

def test_func(arg):
    return [i*i for i in range(arg)]     


print FitFunctionList() 
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print FitFunctionList(func=test_func, args=6) 
# [0, 1, 4, 9, 16, 25]
dawg
  • 98,345
  • 23
  • 131
  • 206