Уведомления

Группа в Telegram: @pythonsu

#1 Июль 25, 2018 21:20:11

Levitanus
Зарегистрирован: 2018-05-01
Сообщения: 46
Репутация: +  0  -
Профиль   Отправить e-mail  

Лист и тип возвращаемых элементов

Делаю лист-подобный класс, и от него требуется по getitem выдавать функционирующий объект, инициализированный положенным значением.
Реализацией в лоб был МАП инициализационной секвенции и последующее создание объектов по append. Но оказалось, что это сильно дорого, и может повесить выполнение на 10 мин при одном листе на 1М элементов.
Вторая попытка в виде отдельной обработки случаев доступа к элементам на местах, вроде была шустрой, но выросла в кашу кода. Сейчас переписываются заново. Думаю, не сяду ли опять в лужу, если буду создавать объекты в getitem по запросу и кешировать их?

Офлайн

#2 Июль 25, 2018 22:28:22

DamMercul
Зарегистрирован: 2017-11-26
Сообщения: 325
Репутация: +  13  -
Профиль   Отправить e-mail  

Лист и тип возвращаемых элементов

Почти ничего не понял, но понимаю в чем проблема. Использую модуль queue, класс Queue. Он вполне себе подходит. 1М объектов для него - фигня, никаких MemoryError не будет, этот модуль не пальцем деланый. А получить 1 объект стоящий последний можно используюя метод .get(), положить .put(). Пример:

 from queue import Queue
queue = Queue()
# Make 1m queue.put(smthing)
object_ = queue.get()

Надеюсь помогло
P.S. Если сможешь - объясни по-проще для сметных пожалуйста)



____________________________________________________

 # Life loop
while alive:
    if (fun > boredom) and money:
        pass_day(fun, boredom, money)
        continue
    else: break

Офлайн

#3 Июль 25, 2018 22:39:33

Levitanus
Зарегистрирован: 2018-05-01
Сообщения: 46
Репутация: +  0  -
Профиль   Отправить e-mail  

Лист и тип возвращаемых элементов

Ох, с планшета ахинея всякая пишется…
Попробую завтра хоть 3g нормальный поймать - точнее ситуацию опишу.
Очередь - не совсем то. Проблема в создании кучи объектов без прямой надобности.

Офлайн

#4 Июль 28, 2018 20:37:41

Levitanus
Зарегистрирован: 2018-05-01
Сообщения: 46
Репутация: +  0  -
Профиль   Отправить e-mail  

Лист и тип возвращаемых элементов

Прошу прощения, только получилось завести интернет на ноут.
В общем, суть проблемы:
Есть лист-подобный класс, который на вход принимает секвенцию. Он может принимать как встроенный тип int, так и кастомный, назовем его Int, у которого есть property value.
При приеме элемента типа Int он вызывает его метод value и сохраняет в приватный list значение int.
А при вызове __getitem__ он должен отдавать уже новый объект Int со своими специфическими атрибутами (допустим,

 my_IntList[0].name == f'{my_IntList.name}[0]'
).
Вот в первой редакции все выглядело так:
 class IntList:
    def __init__(self, name, seq):
        self._name = name
        self._seq_duck_type(seq)
        self.__seq = self._make_seq(seq)
    def _make_seq(self, seq):
        for idx, item in enumerate(seq):
            if isinstance(item, Int):
                item = item.value
            self.__seq.append(Int(name=f'{self._name}[{idx}]',
                                  value=item))
    def __getitem__(self, idx):
        idx = self._idx_duck_type(idx)
        return self.__seq[idx]
но оказалось, что это вообще ни разу не быстро, ибо
 for item in seq:
    self.__seq.append(item)
по времени выполнения отличается кардинльно от
 for item in seq:
            self.__seq.append(Int(item))
Пожтому по второму проходу был использован вариант сохранения только значений, и возврата их же.
Но последующей обработкой поступающих значений в духе (ну это уже утрированно):
 def func(val, idx=None):
    if idx is None:
        return process(val.name, val.value)
    if isinstance(val, IntList):
        return process(f'{val.name}[{idx}]', val[idx])
короче, каша. Хотя по скорости обработки удоветворительно, т.к. объявление больших массивов - не редкость, а прогон по всем элементам - уже не такая.

Вот сейчас третий проход
выглядит все так:
 class IntList(KspVar):
    def __init__(self, name, ref_type=None, item_type=None,
                 size=None, seq=None):
        super().__init__(name,
                         ref_type=ref_type)
        if not isinstance(item_type, type):
            raise TypeError('item_type has to be subclass of KspVar')
            if not issubclass(item_type, KspVar):
                raise TypeError(
                    'item_type has to be subclass of KspVar')
        self._item_type = item_type
        self.__name = name
        if seq is not None:
            self._seq = self._init_seq(seq)
        else:
            self._seq = list()
        if size is not None:
            if self._seq:
                if len(self._seq) < size:
                    raise AttributeError(
                        'size has to be greater or equal length of seq')
            self._size = size
            self._init_size = size
        else:
            self._size = 0
            self._init_size = None
        self._cashed = [None] * self._size
        def _init_seq(self, seq):
            if not isinstance(seq, list):
                raise TypeError('seq has to be instance of list')
            for item in seq:
                if not isinstance(item, self.ref_type):
                    raise TypeError(
                        'all items of seq have to be instances of' +
                        f'{self.ref_type}')
            return seq
        @property
        def item_type(self):
            return self._item_type
        def extend(self, seq):
            if not isinstance(seq, list):
                raise TypeError('has to be list')
            for val in seq:
                self.append(val)
        def __getitem__(self, idx):
            idx = self._check_idx(idx)
            self._check_cashed_item(idx)
            return self._cashed[idx]
        def __setitem__(self, idx, val):
            idx = self._check_idx(idx)
            self._seq[idx]
            self._check_cashed_item(idx)
            self._cashed[idx] <<= val
        def _check_idx(self, idx):
            if not isinstance(KspIntVar, int):
                raise TypeError('has to be int or int KspIntVar')
            if isinstance(idx, KspIntVar):
                idx = idx.val
            return idx
        def _check_cashed_item(self, idx):
            if self._cashed[idx] is None:
                self._cashed[idx] = \
                    self._item_type(name=f'{self.__name}[{idx}]',
                                    value=self._seq[idx])
на что я еще в перспективе могу напороться, и в плане архитектуры, и в плане производительности?

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version