[Python] permettere l'accesso ad una lista di oggetti in diversi modi

Davide Olianas davide a davideolianas.com
Sab 3 Dic 2016 23:01:40 CET


Ciao lista,

mi trovo a dover lavorare con dei file .xyz che sono dei file di testo 
del genere

|C -3.95384 -0.70179 0.00000 C -3.93661 -2.09651 0.00000 C -2.72014 
-2.77895 -0.00000 C -1.52089 -2.06666 0.00000 C -1.53812 -0.67195 
0.00000 C -2.75460 0.01049 -0.00000 H -4.90162 -0.17009 -0.00000 H 
-4.87097 -2.65146 0.00000 H -2.70671 -3.86559 0.00000 H -0.57311 
-2.59836 0.00000 H -0.60377 -0.11700 -0.00000 H -2.76802 1.09714 -0.00000 |

ovvero ogni riga contiene un atomo con informazione sull’elemento 
atomico e le coordinate. Io ho creato una semplice namedtuple per 
contenere le informazioni sull’atomo

|class Atom(namedtuple('Atom', ['element', 'coords'])): pass atoms = 
[Atom('C', numpy.array([-3.95384, -0.70179, 0.00000])), ... ] |

Facendo il parsing del file di testo posso dunque generare una lista che 
contiene istanze di Atom. Con una lista posso facilmente iterare su 
quello che chiamerò l’indice “globale”. Il problema su cui chiedo 
consigli è che contemporaneamente mi serve poter selezionare un atomo in 
base ad un indice “locale”, ovvero un indice che appartiene all’elemento 
chimico. In questo caso, dovrei poter iterare sul carbonio 6 volte 
(indice da 0 a 5) e sull’idrogeno pure.

Per esempio, vorrei poter fare qualcosa tipo |atoms.byElementIndex('H', 
0)| per selezionare il primo idrogeno.

Che vi pare se faccio una cosa del genere

|class Atoms(list): def __init__(self): super(Atoms, self).__init__() 
self._atoms_by_elem = {} def append(self, atom): super(Atoms, 
self).append(atom) if atom.element not in self._atoms_by_elem.keys(): 
self._atoms_by_elem[atom.element] = [] 
self._atoms_by_elem[atom.element].append(self.index(atom)) def 
byElementIndex(self, element, index): global_index = 
self._atoms_by_elem[element][index] return self[global_index] atoms = 
Atoms() atoms.append(Atom('C', [0, 0, 0])) atoms.append(Atom('C', [0, 0, 
1])) atoms.append(Atom('H', [1, 1, 1])) atoms.append(Atom('C', [0, 1, 
1])) atoms.append(Atom('H', [2, 1, 1])) |

| >>> atoms.byElementIndex('H', 0) Atom(element='H', coords=[1, 1, 1]) |

Ovviamente ora come ora il dizionario e la lista non rimangono 
sincronizzati se rimuovo elementi da |atoms| ma per ora non mi interessa.

Ogni consiglio è ben accetto.

Ciao,

Davide

​
-------------- parte successiva --------------
Un allegato HTML è stato rimosso...
URL: <http://lists.python.it/pipermail/python/attachments/20161203/253676bb/attachment-0001.html>


Maggiori informazioni sulla lista Python