Michael Gao
Michael Gao

Reputation: 79

How to effectively name a large amount of instances in python?

I am doing OOP in python; I have a class called mesh_grid. I need to create a lot of objects. In some cases, I think as many as a million objects, or even more might be needed. Now I want to instantiate this and give the instances their name in a somehow automatic way, as shown in the codes below.

The question is, is using vars()['some string'] the most efficient (computationally less intensive) way to do this? Are there any other better approaches?

class mesh_grid:
    num_mg = 0
    def __init__(self):
        self.coord = ()             # Coordinates
        self.sol_conc = 0           # Solute concentration (physical quantity)
        mesh_grid.num_mg += 1

num_nodes = 20
for num in range(1,num_nodes+1):
    vars()['mg'+str(num)] = mesh_grid()

Upvotes: 0

Views: 341

Answers (1)

Wolf
Wolf

Reputation: 10238

I guess you are interested in creating a lot of objects of type mesh_grid and want to access/display it in a reasonable and effective was later on. Here for example is a list-based solution.

class mesh_grid:
    num_mg = 0
    def __init__(self):
        self.coord = ()             # Coordinates
        self.sol_conc = 0           # Solute concentration (physical quantity)
        mesh_grid.num_mg += 1

nodes = []
for num in range(20):
    nodes.append(mesh_grid())

Mass access (for example output) is possible by

for node in nodes:
    print(node.coord, node.col_conc)

If mesh_grid.num_mg was meant to get the amount of nodes, this can effectively be done by the collection, list in the case shown above.

The following is an example without this class member, I also changed some names: the node class to mesh_node and the collection to mesh_grid because it represents the grid in this case (still implemented by a list). I also allow to specify the member values by passing initialisers to __init__:

Dense mesh

import random # simulate concentrations by random values

class mesh_node:
    def __init__(self, coord = (), sol_conc = 0):
        self.coord = coord
        self.sol_conc = sol_conc

width = 3
height = 3

mesh_grid = []
for i in range(width*height):
    mesh_grid.append(mesh_node((i % width, i // width), random.randint(1, 6)))
   
for node in mesh_grid:
    print(node.coord, node.sol_conc)

Here is an example output:

(0, 0) 2
(1, 0) 3
(2, 0) 5
(0, 1) 1
(1, 1) 3
(2, 1) 1
(0, 2) 6
(1, 2) 6
(2, 2) 4

Sparse mesh

If you are implementing a sparse mesh, it may be better to switch to the dict container. Here you store only existing nodes by using coord as key and sol_concas value:

import random

class MeshGrid:
    nodes = dict()
    def set_node(self, coord, sol_conc):
        self.nodes[coord] = sol_conc
    def __str__(self):
        return '\n'.join([f'{k} {v}' for k, v in self.nodes.items()])
    
width = 100
height = 100

grid = MeshGrid()
for i in range(width*height):
    # simulate that about 1/1000 nodes exist:
    if random.random() > 0.999:
       grid.set_node((i % width, i // width), random.randint(1, 6))
   
print(grid)

Here is the example output of a 100 x 100 grid with nodes in 11 out of 10.000 potential places:

(5, 11) 2
(17, 27) 6
(95, 29) 6
(49, 41) 4
(96, 45) 3
(87, 47) 1
(17, 52) 6
(23, 61) 5
(54, 68) 6
(73, 79) 1
(11, 93) 3

Upvotes: 3

Related Questions