Неупорядоченная коллекция для изменяемых объектов в Python

#python #python-3.x #collections

#python #python-3.x #Коллекции

Вопрос:

Задача, которую я имею под рукой, состоит в том, чтобы проанализировать большой текстовый файл (несколько строк 100 тыс.) и накопить некоторую статистику, которая затем будет визуализирована на графиках. Каждая строка содержит результаты некоторого предварительного анализа.

Я написал пользовательский класс для определения объектов, которые должны быть накоплены. Класс содержит 2 строковых поля, 3 набора и 2 счетчика целых чисел. Таким образом, существует __init__(self, name) функция, которая инициализирует новый объект с именем и пустыми полями, и вызываемый метод addRow() , который добавляет информацию в объект. Наборы накапливают данные, которые должны быть связаны с этим объектом, а счетчики отслеживают пару условий.

Моя первоначальная идея состояла в том, чтобы перебирать строки файла и вызывать метод, подобный parseRow() in main

 reader = csv.reader(f)
acc = {} # or set()
for row in reader: 
  parseRow(row,acc)
  

что будет выглядеть примерно так:

 parseRow(row, acc):
  if row[id] is not in acc: # row[id] is the column where the object names/ids are 
    a = MyObj(row[id])
  else:
    a = acc.get(row[id]) # or equivalent
  a.addRow(...)
  

Проблема здесь в том, что накапливающаяся коллекция acc не может быть a set , поскольку наборы, по-видимому, не индексируются в Python. Редактировать: для пояснения, под индексируемым я имел в виду не получение n-го элемента, а возможность извлечения определенного элемента.

Одним из обходных путей было бы иметь a dict , который имеет {obj_name : obj} отображение, но это похоже на уродливое решение. Учитывая элегантность языка в противном случае, я думаю, есть лучшее решение для этого. Это, конечно, не особенно редкая ситуация…

Есть предложения?

Комментарии:

1. Как у вас может быть что-то неупорядоченное и индексируемое? Что значит получить первое из неупорядоченной коллекции?

2. @jonrsharpe мой плохой, под индексируемым я имел в виду что-то, где вы можете выполнить операцию get a la d["myitem"] или подобное s.get("myitem")

3. Неясно, почему dict «чувствует» себя «уродливым» решением. Вы хотите что-то индексировать (изменяемый объект) со значением (неизменяемый объект). Это dict. Объект Python dict имеет очень хороший метод setdefault, который может сжать вашу функцию parseRow до oneliner . Однако вопрос не ясен — что такое строка, идентификатор, acc? Как заполняется acc?

4. @oekopez попытался уточнить детали программирования. Что касается того, почему это похоже на взлом, то это потому, что я сохраняю одно и то же дважды, используя dict {id : myobj} , если myobj поле уже сохранено id .

5. Вот почему вы должны указать «Я хочу избежать накладных расходов на память», а не писать «уродливо», что бросается в глаза смотрящему. Чтобы избежать перегрузки памяти в ограниченной системе, я бы предложил переместить идентификатор из класса в индекс. Если вы не страдаете от ограничений памяти, я бы не стал беспокоиться, а написал читаемый код. Пожалуйста, избегайте «ощущения» и «уродливости» в вашем вопросе, а скорее сформулируйте проблему. Вы можете делать действительно приятные вещи с помощью dicts. Любой изготовленный на заказ контейнер, вероятно, будет чрезмерно усложнять несуществующую проблему и, безусловно, медленнее, чем встроенный поиск dict.

Ответ №1:

Вы также можете попробовать упорядоченный набор. Которая является набором и упорядочена.