WedX - журнал о программировании и компьютерных науках

Класс, который перебирает набор

class Ordered:
    def __init__(self,aset):
        self.aset = aset
    def __iter__(self):
        for v in sorted(self.aset): # iterate over list of values returned by sorted
            yield v

функция принимает набор и возвращает список

набор всегда

s = {1, 2, 4, 8, 16}

Например:

s = {1, 2, 4, 8, 16}
i = iter(Ordered(s))
print(next(i))
print(next(i))
s.remove(8)
print(next(i))
s.add(32)
print(next(i))
print(next(i))

it should prints 1 2 4 16 32

Но когда моя функция принимает

[next(i), next(i), s.remove(8), next(i), next(i), s.add(32), next(i)]

он должен печатать

[1, 2, None, 4, 16, None, 32]

Но вместо этого он печатает:

[1, 2, None, 4, 8, None, 16]

может кто-нибудь сказать мне, как это исправить? Благодарность

Я разместил сообщение об ошибке, которое я получил ниже, чтобы помочь понять:

39 *Error: Failed [next(i), next(i), s.remove(8), next(i), next(i), s.add(32), next(i)] == [1, 2, None, 4, 16, None, 32]
      evaluated: [1, 2, None, 4, 8, None, 16] == [1, 2, None, 4, 16, None, 32]
42 *Error: [next(i), next(i), next(i), s.add(3), next(i), s.add(10), s.add(32), next(i), next(i), next(i)] raised exception; unevaluated: [1, 2, 4, None, 8, None, None, 10, 16, 32]
46 *Error: Failed [next(i), s.remove(2), s.remove(4), s.remove(8), next(i)] == [1, None, None, None, 16]
      evaluated: [1, None, None, None, 2] == [1, None, None, None, 16]
49 *Error: Failed [next(i), s.remove(2), next(i), s.remove(4), s.remove(8), next(i)] == [1, None, 4, None, None, 16]
      evaluated: [1, None, 2, None, None, 4] == [1, None, 4, None, None, 16]
28.10.2016

  • Итератор больше недействителен после того, как вы что-то удалили. 28.10.2016
  • но как я могу это исправить? 28.10.2016
  • может ли кто-нибудь помочь мне исправить это? 28.10.2016

Ответы:


1

Функция sorted() сортирует аргумент и возвращает список. Изменение входного набора не повлияет на отсортированный список.

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

28.10.2016

2

Когда вы используете sorted, вы создаете отсортированный список из набора. Этот список не связан с исходным набором, из которого он был создан, и не будет отражать никаких изменений в этом наборе. Вам придется самостоятельно отслеживать изменения, перебирая элементы в отсортированном порядке.

Отследить удаленные элементы очень просто: просто проверьте, находится ли текущий элемент в исходном наборе. Отслеживание новых элементов немного сложнее. Вы можете использовать модуль heapq и создать куча из набора вместо отсортированного списка, то вы можете добавлять новые элементы в эту кучу во время ее итерации. Чтобы найти новые элементы, создайте копию исходного набора и сравните их на каждой итерации. Также, согласно вашим тестовым примерам, вы должны будете проверить, меньше ли текущий элемент, чем предыдущий, и пропустить его в этом случае.

import heapq

class Ordered:

    def __init__(self,aset):
        self.aset = aset

    def __iter__(self):
        # memorize original elements
        known = set(self.aset)
        last = None

        # create heap
        heap = list(self.aset)
        heapq.heapify(heap)

        # yield from heap
        while heap:
            v = heapq.heappop(heap)
            if (v in self.aset and  # not removed
                    (last is None or last < v)): # not smaller than last
                yield v
            last = v

            # in case of new elements, update the heap
            diff = self.aset - known
            if diff:
                for x in self.aset - known:
                    heapq.heappush(heap, x)
                known = set(self.aset)

Это работает для всех ваших тестовых случаев (повторная инициализация s и i не показана):

>>> s = {1, 2, 4, 8, 16}
>>> i = iter(Ordered(s))
>>> [next(i), next(i), s.remove(8), next(i), next(i), s.add(32), next(i)]
[1, 2, None, 4, 16, None, 32]
>>> [next(i), next(i), next(i), s.add(3), next(i), s.add(10), s.add(32), next(i), next(i), next(i)]
[1, 2, 4, None, 8, None, None, 10, 16, 32])
>>> [next(i), s.remove(2), s.remove(4), s.remove(8), next(i)]
[1, None, None, None, 16]
>>> [next(i), s.remove(2), next(i), s.remove(4), s.remove(8), next(i)]
[1, None, 4, None, None, 16]
28.10.2016
Новые материалы

Как создать диаграмму градиентной кисти с помощью D3.js
Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

Объяснение документов 02: BERT
BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

Как проанализировать работу вашего классификатора?
Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

Работа с цепями Маркова, часть 4 (Машинное обучение)
Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


Для любых предложений по сайту: [email protected]