Python – What is the best way to dynamically store information that are currently in lists

Question:

I have a class that keeps track of some data in my code. For the example, we’ll speak about storing unique 3D points. I have the following class that stores points coordinates, each of them with a unique id, not especially in sequence:

class PointManager:

    def __init__(self):
        self._ids = []
        self._points = []

    def get_point(self, id):
        i = self._ids.index(id)  # No checks to keep example light
        return self._points[i]

    def add_point(self, point):
        new_id = np.max(self._ids) + 1
        self._ids.append(new_id)
        self._points.append(point)

    def delete_point(id):
        i = self._ids.index(id)  # No checks to keep example light
        del self._ids[i]
        del self._points[i]

In real-life, I have some checks and decorators that assure every time that things are kept tidy (mainly that two lists have the same length).

However, Lists in python become slower as they grow (as they are chained lists in C and therefore need to go through all elements before arriving to the requested one). I am not working with Numpy arrays as modifying the array requires a full copy of it and new memory allocation, freeing the previous one, thus being less efficient (am I right?).

More importantly, I feel like this way of doing is dirty… Do you have any recommendation of how to make this kind of storage cleaner and more efficient? Or is it just me?

Thanks very much for any advice.

Asked By: Maltergate

||

Answers:

You need to use dicts. This example you gave – it’s log(n) at best. It’s also preposterously fragile.

First you index an element in an array, then you pull an element out of another array by that same index. There’s too wide a margin to make mistakes.

Just use a dictionary:

class PointManager:

    def __init__(self):
        self._points = dict()

    def get_point(self, i):
        # No checks to keep example light
        return self._points[i]

    def add_point(self, point):
        new_id = (max(self._points.keys()) + 1) if self._points else 0
        self._points[new_id] = point

    def delete_point(i):
        # No checks to keep example light
        del self._points[i]
Answered By: Vsevolod Timchenko
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.