Skip to content Skip to sidebar Skip to footer

Wrapping Big List In Python 2.7 To Make It Immutable

In case I have a really big list (>100k elements) that can be retrieved from some object through function call, is there a way to wrap that list to make it immutable to the call

Solution 1:

Unfortunately, there is no such wrapper in the standard library (or other prominent libraries). The main reason is that list is supposed to be a mutable sequence type with index access. The immutable sequence type would be a tuple as you already said yourself. So usually, the standard approach to make a list immutable would be to make it into a tuple by calling tuple(lst).

This is obviously not what you want, as you want to avoid to copy all the elements. So instead, you can create a custom type that wraps the list, and offers all non-modifying methods list also supports:

classImmutableList:
    def__init__ (self, actualList):
        self.__lst = actualList
    def__len__ (self):
        return self.__lst.__len__()
    def__getitem__ (self, key):
        return self.__lst.__getitem__(key)
    def__iter__ (self):
        return self.__lst.__iter__()
    def__reversed__ (self):
        return self.__lst.__reversed__()
    def__contains__ (self, item):
        return self.__lst.__contains__(item)
    def__repr__ (self):
        return self.__lst.__repr__()
    def__str__ (self):
        return self.__lst.__str__()
>>>original = [1, 2, 3, 4]>>>immutable = ImmutableList(original)>>>immutable
[1, 2, 3, 4]
>>>immutable[2]
3
>>>for i in immutable:
        print(i, end='; ')

1; 2; 3; 4; 
>>>list(reversed(immutable))
[4, 3, 2, 1]
>>>immutable[1] = 4
Traceback (most recent call last):
  File "<pyshell#39>", line 1, in <module>
    immutable[1] = 4
TypeError: 'ImmutableList' object does not support item assignment

The alternative would be to subtype list and override __setitem__ and __delitem__ to raise an exception instead, but I would suggest against that, as a subtype of list would be expected to have the same interface as list itself. ImmutableList above on the other hand is just some indexable sequence type which happens to wrap a real list itself. Apart from that, having it as a subtype of list would actually require you to copy the contents once, so wrapping is definitely better if you don’t want to recreate all those items (which seems to be your point—otherwise you could just use tuple).

Solution 2:

See Emulating Container Types for the "special" methods you'd want to implement or override. Namely, you'd want to implement __setitem__ and __delitem__ methods to raise an exception, so the list cannot be modified.

Post a Comment for "Wrapping Big List In Python 2.7 To Make It Immutable"