21

Is there a way to make an automatically growing list in Python? What I mean is to make a list that would grow when an index that does not yet exist is referenced. Basically the behaviour of Ruby arrays.

Thanks in advance!

8
  • Umm, you're describing the way lists work. What are you trying that isn't working? Commented Dec 28, 2010 at 8:18
  • What I mean is that if the context is out of range, it will raise an error. I want the list to grow to a size where the index is accommodated; in Ruby this will fill all the intermediary spots with Nulls. Commented Dec 28, 2010 at 8:20
  • 1
    What do you want the contents of the not-yet-existing index to be when it is first referenced (and all the elements before it)? Should it be None or some other default value? Commented Dec 28, 2010 at 8:23
  • 1
    It should be what it is assigned; so a[100]=20 for example. I don't care what the empty spots are assigned, as these are overwritten later. Commented Dec 28, 2010 at 8:25
  • 1
    OK, and what do you want to happen if someone asks for the value of a[1000] if it doesn't exist yet? IndexError or should the list grow to this size, too? Commented Dec 28, 2010 at 8:27

3 Answers 3

47

Sure it's possible, you just have to use a subclass of list to do it.

class GrowingList(list):
    def __setitem__(self, index, value):
        if index >= len(self):
            self.extend([None]*(index + 1 - len(self)))
        list.__setitem__(self, index, value)

Usage:

>>> grow = GrowingList()
>>> grow[10] = 4
>>> len(grow)
11
>>> grow
[None, None, None, None, None, None, None, None, None, None, 4]
Sign up to request clarification or add additional context in comments.

13 Comments

Just note that this is only really useful for dense arrays, if you need a structure for sparse arrays then you are better off with a dictionary based solution.
add a 'fillvalue' argument in the function...so you can do grow.__setitem__(10, 4, True) for example
@Ant, __setitem__ is a special method, it's not often called via it's name, but like in the example grow[10] = 4.
i know, but if i really want that behaviour, i should be able to do that without rewriting the func. and doing def __setitem__(self, index, value, fillvalue=None) won't affect the normal usage ;)
I don't think it is good python to add parameters (even default parameters) to special functions, what if the specification changes and it adds another parameter. I think if you need a fillvalue then you should add it to the __init__ function, but that wouldn't play well with being inherited from list, you'd need to change the __new__ method, but I'm just trying to write a simple example.
|
2

Lists are dynamic in python. It will automatically grow always (up until you hit sys.maxsize) in your program.

  l = list()
  l.append(item)

Keep doing that.

3 Comments

No, I mean that it will grow when an out-of-range index is referenced. For example, a=[1,2,3] will grow when a[100]=101 is called.
What should the values of a[3] to a[99] be after this?
In Ruby, intermediate elements are set to nil; in Python, None would be the logical choice.
-1

No, but you could use a dictionary (hash table) to achieve the same thing.

4 Comments

Thanks, but I need it to be ordered.
Then you might try the OrderedDict object. ;-)
They have keys which would act like indices. Not much difference, but saves memory on sparse arrays. The extended list (alternative) approach would also allocate a bunch of unused objects, and also add run time cost to list traversal.
I see what you mean. However, the reason I wanted this is for implementing a mathematical algorithm where the values of indeces are significant.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.