2

I am trying to make an class = that extends from list return a slice of itself instead of a list type. The reason I want to do this is because I have many other methods to manipulate the instance of A.
I am running python 2.7.3 Say I have:

class B():
def __init__(self, t, p):
    self.t = t
    self.p = p

class Alist(list):
    def __init__(self, a_list_of_times = []):
        for a_time in a_list_of_times:
            self.append(a_time )
    def __getslice__(self, i, j):
        return super(Alist, self).__getslice__(i,j)

    def plot_me(self):
        pass
        # other code goes here!


alist1 = Alist()
for i in range(0, 1000000):
    alist1.append(B(i, i))                  # yes ten million, very large list!
alist = alist1[1000:200000]                 # will return a list!
alist2 = Alist(alist)                # will return Alist istance 

The problem is that remaking the entire list as seen in making variable b is VERY VERY SLOW (comparative to the slice). What I want to do is simply change the class of alist (currently of type list)to Alist

When I try:

alist.__class__ = Alist
>>>> TypeError: __class__ assignment: only for heap types.

Which is very sad since I can do this for my own object types. I understand that it is not standard, but it is done. Reclassing an instance in Python.

Is there a way around this? Also I have obviously simplified the problem, where my objects a bit more complex. Mainly what I am finding is that remaking the list into my Alist version is slow. And I need to do this operation a lot (unavoidable). Is there a way to remake A? or a solution to this to make it speed up?

In my version, I can do about a 10,000 (size of my slice) slice in 0.07 seconds, and converting it to my version of Alist takes 3 seconds.

Community
  • 1
  • 1
user1639926
  • 852
  • 2
  • 11
  • 21
  • 1
    I think a little bit of reading up on object oriented programming will help you. Python uses C to internally perform list operations (like slices), but building `Alist` by manually appending a million elements in pure python will always be super slow. Instead, you should use the native list methods wherever you can and wrap the result in an Alist constructor, then return the Alist directly from the method. You're a long way off from needing something hacky like assigning to \_\_class__. – Dylan MacKenzie Sep 26 '13 at 01:47

1 Answers1

1

The UserList class (moved to collections in Python 3) is perfectly designed for this. It is a list by all other means but has a data attribute that you can store an underlying list in without copying.

from UserList import UserList

class Alist(UserList):
    def __init__(self, iterable, copy=True):
        if copy:
            super(Alist, self).__init__(iterable)

        else:
            self.data = iterable

    def plot_me(self):
        pass
Veedrac
  • 58,273
  • 15
  • 112
  • 169
  • this is very awesome! I simply did as you said, changed class Alist(list) to Alist(userlist), and things worked. Quick question though. If I added a quick check to make sure everything in "iterable" was the correct object type, would it slow things down much? like if type(x) == datetime for x in iterable (not pythonic just i know just wanted to see if feasible!) – user1639926 Sep 26 '13 at 03:55