Простая уникальная система очередей без приоритетов

1

Я работаю над простым веб-искателем в python, и я не хочу создавать простой класс очереди, но я не совсем уверен, как лучше всего начать. Я хочу что-то, что содержит только уникальные элементы для обработки, так что искатель будет сканировать только одну страницу за один раз за script (просто чтобы избежать бесконечного цикла). Может ли кто-нибудь дать мне или указать на простой пример очереди, с которым я мог бы убежать?

  • 0
    сколько страниц вы собираетесь проиндексировать? Ваш индекс будет сохраняться на диске?
  • 0
    Этот веб-сканер должен быть написан с нуля? В Python уже есть ряд фреймворков / модулей для этого, таких как Scrapy.
Теги:
queue

5 ответов

4
Лучший ответ

Я бы просто использовал набор, он не поддерживает порядок, но он поможет вам сохранить уникальность:

>>> q = set([9, 8, 7, 7, 8, 5, 4, 1])
>>> q.pop()
1
>>> q.pop()
4
>>> q.pop()
5
>>> q.add(3)
>>> q.add(3)
>>> q.add(3)
>>> q.add(3)
>>> q
set([3, 7, 8, 9]
  • 0
    @ S.Lott да, я вижу это сейчас, но первоначально в его ответе говорилось, что
  • 0
    @ S.Lott он отвечал на мой первоначальный ответ, который должен был предложить heapq, потому что я неправильно прочитал его вопрос и хотя он хотел очереди с приоритетами.
Показать ещё 2 комментария
2

Очень простой пример - набить каждый элемент URL в dict, но как ключ, а не как значение. Затем обрабатывать только следующий элемент, если он не находится в этих ключах:

visited = {}
# grab next url from somewhere
if url not in visited.keys():
  # process url
  visited[url] = 1 # or whatever, the value is unimportant
# repeat with next url

Вы можете получить более эффективную, конечно, но это было бы просто.

  • 0
    По сути, это реализация набора - фактически встроенный набор python реализован аналогичным образом.
  • 0
    Да, но в то время, когда я публиковал его, предыдущий постер использовал heapq, а не набор.
Показать ещё 2 комментария
2

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

Я бы использовал комбинацию набора и списка:

visited = set()
to_visit = []

def queue_page(url):
    if url not in visited:
        to_visit.append(url)

def visit(url):
    visited.add(url)
    ... # some processing

    # Add all found links to the queue
    for link in links:
        queue_page(link)

def page_iterator(start_url):
    visit(start_url)
    try:
        yield to_visit.pop(0)
    except IndexError:
        raise StopIteration

for page in page_iterator(start):
    visit(page)

Конечно, это немного надуманный пример, и вы, вероятно, лучше всего инкапсулируете это каким-то образом, но это иллюстрирует концепцию.

1

Почему бы вам не использовать список, если вам нужен заказ (или даже heapq, как ранее предлагалось захатерами до того, как был предложен набор), а также использовать набор для проверки дубликатов?

0

Я бы расширил класс списка, чтобы добавить код уникального тестирования ко всем методам используемого вами списка. Это может варьироваться от простого добавления класса .append_unique(item) к классу или переопределения всех append, insert, extend, __setitem__, __setslice__ и т.д., Для генерирования исключения (или молчания, если вы хотите) в случае неповторимого элемента.

Например, если вы просто хотели убедиться, что метод append поддерживает уникальность:

class UniqueList(list):
    def append(self, item):
        if item not in self:
            list.append(self, item)
  • 0
    Разве набор не будет проще? Хотя список сохраняет порядок, что необходимо для сохранения порядка?
  • 0
    Я предполагал, что очередь будет означать, что она упорядочена, но я предполагаю, что именно об этом «неприоритетная» часть ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню