Python удалить набор из набора
согласно моей интерпретации документации Python 2.7.2 для Встроенные Типы 5.7 Набор Типов, это должно быть возможным, чтобы удалить элементы множества A от множества B, передав в 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)
который возвращает новый набор; или set.difference_update(other)
; или с набором операторов a -= b
, которые изменяют набор на месте.
так это a ошибка в документации? Может set.remove(elem)
на самом деле не взять в качестве аргумента? Или документация относится к наборам наборов? Учитывая, что difference_update
выполняет мою интерпретацию, я думаю, дело в последнем.
это достаточно непонятно?
EDIT После 3 лет дополнительной (какой-то профессиональной) работы python, и недавно вернувшись к этому вопросу, я теперь понимаю, что я на самом деле пытался сделать, можно было бы выполнить с:
>>> c = a.difference(b)
set([0,1,2,3,4])
что я изначально пытался сделать.
4 ответа:
вы уже ответили на вопрос. Это относится к наборам наборов (на самом деле наборы, содержащие frozensets).
абзац, на который вы ссылаетесь начинается с:
обратите внимание, что аргумент elem для __содержит__ (), remove () и discard() методы могут быть заданы.
что означает
b
наa.remove(b)
может быть набор, а затем продолжается с:для поддержки поиска эквивалента frozenset, набор элементов временно мутирует во время поиска, а затем восстанавливается. Во время поиска набор элементов не должен быть прочитан или изменен, так как он не имеет значимого значения.
это означает, что если
b
- Это набор,a.remove(b)
просканируетa
для замороженного эквивалентаb
и удалить его (или кинутьKeyError
если он не существует).
вы не можете иметь
set
Сset
s в 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
Сfrozenset
s.
Я смотрю на встроенную справку для различных версий python (для mac). Вот результаты.
- вместо python2.5
удалить(...)
Удалите элемент из набора; он должен быть членом.
Если элемент не является членом, поднять KeyError.
- вместо python2.6
удалить(...)
Удалите элемент из набора; он должен быть членом. Если элемент не является членом, поднимите KeyError.
- вместо python2.7
удалить(...)
Удалите элемент из набора; он должен быть членом. Если элемент не является членом, поднять KeyError.документация, на которую вы ссылаетесь, в полном объеме, на самом деле говорит:
обратите внимание, аргумент elem для
__contains__()
,remove()
иdiscard()
методы могут быть набор. Для поддержки поиска эквивалента frozenset, набор элементов временно мутирует во время поиска, а затем восстанавливается.Это похоже на сноску, которая предполагает, что аргумент может быть набором, но если он не найдет соответствующий замороженный набор в наборе, он не будет удален. Упоминание о наборе, который изменяется, так что он может быть хэширован, чтобы искать соответствующий замороженный набор.