Python: Набор только с проверкой существования?

Необходимо использовать эти id атрибут вместо этого. Работают тот же путь, и Вам не нужно искусственное <a name=...>, но просто

<h2 id="one">Section One</h2>
8
задан Peter Mortensen 14 March 2011 в 13:30
поделиться

6 ответов

Конечно, можно сохранить набор только хешей:

done = set()
while len(queue) > 0 :
   item = queue.pop()
   h = hash(item)
   if h not in done :
      process(item)
      done.add(h)

Обратите внимание, что из-за конфликтов хешей есть шанс, что вы считаете элемент выполненным, даже если это не так.

Если вы не можете принять этот риск, вам действительно нужно сохранить полные строки, чтобы можно было определить, видели ли вы это раньше. В качестве альтернативы: возможно, сама обработка сможет определить это?

Или же: если вы не можете принять сохранение строк в памяти, храните их в базе данных или создавайте файлы в каталоге с тем же именем, что и строка.

10
ответ дан 5 December 2019 в 07:12
поделиться

Специально для этой цели можно использовать структуру данных, называемую Фильтр Блума . Реализацию Python можно найти здесь .

РЕДАКТИРОВАТЬ : Важные примечания:

  1. Ложные срабатывания возможны в этой структуре данных, то есть проверка на наличие строка может вернуть положительный результат, даже если она не сохранена.
  2. Ложноотрицательные результаты (получение отрицательного результата для строки, которая была сохранена) невозможны.

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

4
ответ дан 5 December 2019 в 07:12
поделиться

Если вы используете безопасную (например, SHA-256, найденную в модуле hashlib ) хеш-функцию для хеширования строк, очень маловероятно, что вы обнаружите дубликаты (и если вы найдете такие, вы, вероятно, сможете выиграть приз, как и в большинстве криптографических хеш-функций).

Встроенный метод __ hash __ () не гарантирует, что у вас не будет дубликатов (и поскольку он использует только 32 бита) , очень вероятно, что вы их найдете).

4
ответ дан 5 December 2019 в 07:12
поделиться

Как уже указывалось, если предложенные здесь ответы (большинство из которых не работают из-за хэш-коллизий) неприемлемы, вам нужно будет использовать представление строк без потерь.

Модуль Python zlib предоставляет встроенные возможности сжатия строк и может использоваться для предварительной обработки строк перед их добавлением в набор. Обратите внимание, однако, что строки должны быть довольно длинными (на что вы намекаете) и иметь минимальную энтропию, чтобы сэкономить много места в памяти. Другие варианты сжатия могут обеспечить лучшую экономию места, и некоторые реализации на основе Python можно найти здесь

0
ответ дан 5 December 2019 в 07:12
поделиться

Вам нужно знать всю строку, чтобы иметь 100% уверенность. Если у вас много строк с похожими префиксами, вы можете сэкономить место, используя дерево для хранения строк. Если у вас длинные строки, вы также можете сэкономить место, используя большую хеш-функцию, такую ​​как SHA-1, чтобы сделать возможность хеш-коллизий настолько маловероятной, что это не имеет значения.

Если вы можете сделать процесс () идемпотентная функция - то есть, если она вызывается дважды для элемента, это всего лишь проблема производительности, тогда проблема становится намного проще, и вы можете использовать структуры данных с потерями, такие как фильтры Блума.

3
ответ дан 5 December 2019 в 07:12
поделиться

Они также появляются время от времени, когда я кодирую. Вы могли бы подумать о переносе второго оператора using в другую функцию?

но __ eq __ не лишняя деталь, которую вы можете сохранить; у вас должны быть две строки для сравнения.

Если вам нужно только отрицательное подтверждение (этот элемент не является частью набора), вы можете заполнить коллекцию Set, которую вы реализовали сами, своими строками, затем вы "завершите" набор удаляя все строки, кроме тех, которые имеют коллизии (они сохраняются для eq тестов), и вы обещаете не добавлять больше объектов в свой Набор. Теперь у вас есть эксклюзивный тест ... вы можете определить, находится ли объект не в вашем наборе. Вы не можете быть уверены, является ли «obj in Set == True» ложным срабатыванием или нет.

Изменить: это в основном фильтр Блума, который был умно связан, но фильтр Блума может использовать более одного хеша для каждого элемента что действительно умно.

Edit2: Это мой 3-минутный фильтр цветения:

class BloomFilter (object):
    """ 
    Let's make a bloom filter
    http://en.wikipedia.org/wiki/Bloom_filter

    __contains__ has false positives, but never false negatives
    """ 
    def __init__(self, hashes=(hash, )): 
        self.hashes = hashes
        self.data = set()
    def __contains__(self, obj):
        return all((h(obj) in self.data) for h in self.hashes)
    def add(self, obj):
        self.data.update(h(obj) for h in self.hashes)
2
ответ дан 5 December 2019 в 07:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: