Python удаляет набор из набора - программирование
Подтвердить что ты не робот

Python удаляет набор из набора

Согласно моей интерпретации документации Python 2.7.2 для встроенных типов 5.7 Set Types, должно быть возможно удалить элементы установите A из множества B, передав A на set.remove(elem) или set.discard(elem)

Из документации для 2.7.2:

Обратите внимание, что аргумент elem для __contains__(), remove() и discard()методы могут быть набором.

Я интерпретирую это как означающее, что я могу передать set в remove(elem) или discard(elem), и все эти элементы будут удалены из целевого набора. Я бы использовал это, чтобы сделать что-то странное, как удалить все гласные из строки или удалить все распространенные слова из истории слов. Здесь тестовый код:

Python 2.7.2 (default, Jun 12 2011, 14:24:46) [M...
Type "help", "copyright", "credits" or "license"
>>> a = set(range(10))
>>> b = set(range(5,10))
>>> a
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b
set([8, 9, 5, 6, 7])
>>> a.remove(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: set([8, 9, 5, 6, 7])
>>> a.discard(b)
>>> a
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>>

Что я ожидаю вернуть:

>>> a
set([0, 1, 2, 3, 4])

Я знаю, что могу выполнить это с помощью a.difference(b), который возвращает новый набор; или с a set.difference_update(other); или с операторами-операторами a -= b, которые изменяют набор на месте.

Так это ошибка в документации? Может ли set.remove(elem) фактически не принимать набор в качестве аргумента? Или документация относится к наборам наборов? Учитывая, что difference_update выполняет мою интерпретацию, я предполагаю, что дело в последнем.

Это недостаточно ясно?

ИЗМЕНИТЬ После 3 лет дополнительной (некоторой профессиональной) работы python и недавно обратившись к этому вопросу, я понимаю, что то, что я на самом деле пытаюсь сделать, может быть достигнуто с помощью:

>>> c = a.difference(b)
set([0,1,2,3,4])

из-за которого я изначально пытался получить.

4b9b3361

Ответ 1

Вы уже ответили на вопрос. Это относится к наборам множеств (фактически наборов, содержащих фризонсет).

Параграф, на который вы ссылаетесь, начинается с:

Обратите внимание, что аргумент elem методам __contains __(), remove() и discard() может быть набором.

что означает, что b в a.remove(b) может быть множеством, а затем продолжается:

Чтобы поддерживать поиск эквивалентного frozenset, набор элементов временно мутируется во время поиска и затем восстанавливается. Во время поиска набор элементов не должен читаться или мутировать, поскольку он не имеет значимого значения.

что означает, что если b является множеством, a.remove(b) будет сканировать a для фениснета, эквивалентного b, и удалить его (или выбросить KeyError, если он не существует).

Ответ 2

У вас не может быть set of set в Python, поскольку set изменен. Вместо этого вы можете иметь set от frozenset s. С другой стороны, вы можете вызвать __contains__(), remove() и discard() с помощью set. См. Этот пример:

a = set([frozenset([2])])
set([2]) in a       # you get True
a.remove(set([2]))  # a is now empty

Итак, ответ на ваш вопрос заключается в том, что документация относится к set of frozenset s.

Ответ 3

Я смотрю встроенную справку для различных версий python (для mac). Вот результаты.

  • python2.5

удалить (...)
    Удалите элемент из набора; он должен быть участником.
    Если элемент не является членом, поднимите KeyError.

  • python2.6

удалить (...)
    Удалите элемент из набора; он должен быть членом.     Если элемент не является членом, поднимите KeyError.

  • python2.7

удалить (...)
    Удалите элемент из набора; он должен быть членом.     Если элемент не является членом, поднимите KeyError.

В документации, на которую вы ссылаетесь, в полном объеме, фактически говорится:

Обратите внимание, что аргумент elem методам __contains__(), remove() и discard() может быть набором. Для поддержки поиска эквивалентного параметра frozenset набор элементов временно мутируется во время поиска и затем восстанавливается.

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

Ответ 4

Я думаю, что документация относится к наборам (замороженных) наборов, да.