Объект против словаря: как организовать дерево данных? - PullRequest
5 голосов
/ 18 июня 2011

Я программирую какую-то симуляцию с данными, организованными в виде дерева.Основным объектом является World, который содержит набор методов и список City объектов.Каждый объект City в свою очередь имеет набор методов и список объектов PopulationPopulation объектов нет собственного метода, они просто содержат атрибуты.

Мой вопрос касается последних Population объектов, которые я могу либо извлечь из object, либо создать как словари.Каков наиболее эффективный способ их организации?

Вот несколько случаев, которые иллюстрируют мои сомнения:

Сохранение данных
Мне нужно иметь возможность сохранить и загрузить симуляцию, для чего я использую встроенный JSON (я хочу, чтобы данные были удобочитаемыми для человека).Поскольку программа организована в виде дерева, сохранение данных на каждом уровне может быть громоздким.В этом случае совокупность лучше всего хранить в виде словаря, добавляемого в список population, в качестве атрибута экземпляра City.Таким образом, сохранение - это просто передача City экземпляра __dict__ в Json.

Использование данных
Если я хочу манипулировать данными о населении, этопроще как экземпляр класса, чем как словарь.Мало того, что синтаксис прост, но я также могу наслаждаться функциями самоанализа лучше при кодировании.

Производительность
Я, наконец, не уверен, что является наиболее эффективным с точки зренияресурсов.Объект и словарь имеют небольшую разницу в конце, поскольку каждый объект имеет атрибут __dict__, который можно использовать для доступа ко всем его атрибутам.Если я запущу симуляцию с большим количеством объектов City и Population, что будет использовать меньше ресурсов: объекты или словари?

Итак, еще раз, каков наиболее эффективный способ организации данных вдерево?Словари или объекты предпочтительнее?Или есть какой-то секрет в организации деревьев данных?

Ответы [ 4 ]

2 голосов
/ 18 июня 2011

Я думаю, вам следует рассмотреть возможность использования namedtuple (см. Документы Python в модуле collections). Вы получаете доступ к атрибутам объекта Population по имени, как если бы вы работали с обычным классом, например population.attribute_name вместо population['attribute_name'] для словаря. Поскольку вы не добавляете никаких методов в класс Population, это все, что вам нужно.

Для вашего критерия "сохранения данных" есть также метод _asdict, который возвращает словарь имен полей для значений, которые вы можете передать в json. (Возможно, вам нужно быть осторожным с тем, что именно вы получите от этого метода, в зависимости от того, какую версию Python вы используете. Некоторые версии возвращают словарь, а другие возвращают OrderedDict. Это может не иметь никакого значения для ваших целей .)

namedtuples также довольно легковесны, поэтому они также работают с вашим требованием к ресурсам «Запуск симуляции». Тем не менее, я бы повторил предостережение других людей, сказав, что не стоит беспокоиться об этом, разницы будет очень мало, если вы не будете серьезно обрабатывать данные.

2 голосов
/ 18 июня 2011

Как вы сами видели, практических различий мало - главное, на мой взгляд, заключается в том, что использование отдельных жестко закодированных атрибутов несколько проще с объектами (не нужно указывать имя в кавычках), тогда как диктовки легко позволяютрассматривая все значения как одну коллекцию (например, суммируя их).Вот почему я бы выбрал объекты, поскольку данные об объектах населения, вероятно, неоднородны и относительно независимы.

2 голосов
/ 18 июня 2011

Почему не гибрид dict / object?

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

Теперь вы можете легко получить доступ к известным именам через атрибуты (foo.bar), сохраняя при этом функциональность dict для простого доступа к неизвестным именам, итерации по ним и т. Д. Без неуклюжего синтаксиса getattr / setattr.

Если вы хотите всегда инициализировать их определенными полями, вы можете добавить метод __init__:

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)
1 голос
/ 18 июня 2011

Я бы сказал, что в каждом случае население является членом города, и если это только данные, почему бы не использовать словарь?

Не беспокойтесь о производительности, но если вам действительно нужно знать, я думаю, что диктат быстрее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...