2011-06-18 10 views
5

Estoy programando algún tipo de simulación con sus datos organizados en un árbol. El objeto principal es World que contiene un conjunto de métodos y una lista de objetos City. Cada objeto City a su vez tiene un montón de métodos y una lista de objetos Population. Population los objetos no tienen ningún método propio, solo tienen atributos.Objeto vs. Diccionario: ¿cómo organizar un árbol de datos?

Mi pregunta se refiere a los últimos Population objetos, que puedo derivar de object o crear como diccionarios. ¿Cuál es la forma más eficiente de organizar estos?

Éstos son algunos casos que ilustran mi duda:

almacenamiento de los datos
tengo que ser capaz de guardar y cargar la simulación, para lo cual se utilizo el built-in json (Quiero que los datos sean humano legible). Debido a que el programa está organizado en un árbol, guardar datos en cada nivel puede ser engorroso. En este caso, la población se conserva mejor como un diccionario adjunto a una lista population como un atributo de una instancia City. De esta manera, el ahorro es una mera cuestión de pasar el City instancia de __dict__ en Json.

Utilizando los datos
Si quiero manipular los datos de la población, es más fácil que una instancia de clase que como un diccionario. No solo es simple la sintaxis, sino que también puedo disfrutar mejor de las funciones de introspección durante la codificación.

Rendimiento
No estoy seguro, por último, en cuanto a lo que es el más eficiente en términos de recursos. Un objeto y un diccionario tienen poca diferencia al final, ya que cada objeto tiene un atributo __dict__, que se puede usar para acceder a todos sus atributos. Si ejecuto mi simulación con un gran número de objetos City y Population, ¿qué utilizará menos recursos: objetos o diccionarios?

De nuevo, ¿cuál es la forma más eficiente de organizar datos en un árbol? ¿Son preferibles los diccionarios u objetos? ¿O hay algún secreto para organizar los árboles de datos?

Respuesta

2

¿Por qué no un híbrido dict/object?

class Population(dict): 
    def __getattr__(self, key): 
     return self[key] 
    def __setattr__(self, key, value): 
     self[key] = value 

ya se puede acceder fácilmente a través de nombres conocidos atributos (foo.bar), sin dejar de tener la funcionalidad dict acceder fácilmente los nombres desconocidos, iterar sobre ellos, etc., sin la sintaxis torpe getattr/setattr.

Si desea inicializar siempre los campos particulares, se puede añadir una __init__ método:

def __init__(self, starting=0, birthrate=100, imrate=10, emrate=10, deathrate=100): 
    self.update(n=starting, b=birthrate, i=imrate, e=emrate, d=deathrate) 
+0

'namedtuple' es, por desgracia, inmutable. – delnan

+0

Vaya, por supuesto. – kindall

+0

y ahora tiene un objeto similar a Javascript, con una función de acceso bidireccional innecesaria. "Debería haber una, y preferiblemente solo una, forma obvia de hacerlo". – Simon

1

Yo diría que en todos los casos una población es miembro de una ciudad, y si solo es de datos, ¿por qué no utilizar un diccionario?

No se preocupe por el rendimiento, pero si realmente necesita saber, creo que un dict es más rápido.

2

Como se ha visto, hay poca diferencia práctica: la principal diferencia, en mi opinión, es que el uso de atributos individuales y codificados es ligeramente más fácil con los objetos (no es necesario citar el nombre) mientras se dicten fácilmente Permitir el tratamiento de todos los valores como una sola colección (por ejemplo, sumarlos). Es por eso que iría por los objetos, ya que los datos de los objetos de población probablemente sean heterogéneos y relativamente independientes.

2

Creo que debería considerar el uso de un namedtuple (ver el Python docs en el módulo collections). Puede acceder a los atributos del objeto Population por nombre como lo haría con una clase normal, p. population.attribute_name en lugar de population['attribute_name'] para un diccionario. Como no está poniendo ningún método en la clase Population, esto es todo lo que necesita.

Para su criterio de "guardado de datos", también hay un método _asdict que devuelve un diccionario de nombres de campo a valores que puede pasar a json. (Es posible que deba tener cuidado con lo que obtiene de este método dependiendo de la versión de Python que esté utilizando. Algunas versiones devuelven un diccionario y algunas devuelven un OrderedDict. Esto puede no tener ninguna importancia para sus propósitos).

namedtuples también son bastante livianos, por lo que también funcionan con el requisito de recursos "Ejecutando la simulación". Sin embargo, me hago eco de la precaución de otras personas al decir que no me preocupo por eso, va a haber muy poca diferencia a menos que estés haciendo un serio crujido de datos.

+3

Nuevamente, 'namedtuple' es inmutable y, por lo tanto, no se puede usar aquí. – delnan

+0

ahh, buen punto, no había pensado en eso – Whatang

Cuestiones relacionadas