Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python List - "reserving" space ( ~ resizing)

I am given a list l and I want to do assignment:

l[index] = val

But there might be a case when the list is too small.

So, I want to ensure I have space for the new value. Sometimes I need to fill the new space with empty strings '', and sometimes with other objects (like empty lists [], False or None).

For this task I use the following procedure:

def ResizeList(l, size, fill_with=None):
    l += [fill_with]*(size-len(l))

(note: it works even if size-len(l)<=0) (note: as I am interested in reserving space, I intentionally DO NOT truncate it to a shorter list)

Like that:

ResizeList(l, index+1)
l[index] = val

(When filling with other object, it's like : ResizeList(l, index+1, []) )

Are there more pythonic ways of doing that? Are there some built-ins or library functions for doing this?

I am using mostly Python-3.x, but know-how about Python-2x is useful and welcome.

Clarification: Please, do not tell me about dict , cause I need list

For those who would like me to be more specific:

The problem statement states it's about list type. Using dict here is not an option or solution. There are reasons for that, specifically related to the domain (I am doing a prototype of an experiment that has to show some asymptotic behaviour, not - as probably you're used to - a prototype of a program. If it would be "just a prototype of a program", then I agree with using a dict and the other comments). I have the following assumptions:

  • I have many many lists (need to care about memory and performance overhead)
  • due to workflow and need of prototype, I cannot call a handcoded C/C++ extension
  • during computation the final list size is unknown
  • we know that in the and the lists will be dense
  • list cells are written and overwritten in an unknown order

Those are just a few reasons why I have stressed that I need a list and not a dict. For those interested in more details or who would like to discuss about dict, checkout how we discuss in comments HERE

like image 416
Grzegorz Wierzowiecki Avatar asked Jan 13 '12 11:01

Grzegorz Wierzowiecki


People also ask

Do Python lists resize?

List resizing. To avoid the cost of resizing, Python does not resize a list every time you need to add or remove an item. Instead, every list has a number of empty slots which are hidden from a user but can be used for new items. If the slots are completely consumed Python over-allocates additional space for them.

Can a list be resized?

The list::resize() is a built-in function in C++ STL which is used to resize a list container. It takes a number n as parameter and resizes the list container to contain exactly n elements. If the list already has more than n elements, then the function erases the elements from the list except the first n element.

Does Python list have size limit?

According to the source code, the maximum size of a list is PY_SSIZE_T_MAX/sizeof(PyObject*) . On a regular 32bit system, this is (4294967295 / 2) / 4 or 536870912. Therefore the maximum size of a python list on a 32 bit system is 536,870,912 elements.

How do I resize an image in a list in Python?

You can resize multiple images in Python with the awesome PIL library and a small help of the os (operating system) library. By using os. listdir() function you can read all the file names in a directory. After that, all you have to do is to create a for loop to open, resize and save each image in the directory.


2 Answers

If you're sure that a list -- and not, say, a dict -- is the best data structure for your use case, I propose the following class:

class rlist(list):
  def __init__(self, default):
    self._default = default
  def __setitem__(self, key, value):
    if key >= len(self):
      self += [self._default] * (key - len(self) + 1)
    super(rlist, self).__setitem__(key, value)

l = rlist(0)
print(l)
l[10] = 20
print(l)
l[5] = 14
print(l)

This class checks whether the index being assigned to is beyond the current length of the list, and automatically expands the list as required.

The code is compatible with both Python 2 and 3 (tested with 2.6.5 and 3.1.2).

This class could be handy if the structure is dense and you need to find the element by index as quickly as possible. If the structure is sparse, you should probably consider using a dictionary.

like image 178
NPE Avatar answered Oct 06 '22 01:10

NPE


Perhaps this does what you want:

def resize(l, newsize, filling=None):                                                                                  
    if newsize > len(l):                                                                                 
        l.extend([filling for x in xrange(len(l), newsize)])                                                 
    else:                                                                                                
        del l[newsize:]                  
like image 22
Mischa Arefiev Avatar answered Oct 05 '22 23:10

Mischa Arefiev