Возникли проблемы при поиске элемента в наборе с использованием ключевого слова «in» в Python - PullRequest
0 голосов
/ 31 октября 2018

У меня есть этот код здесь.

import spacy
nlp = spacy.load('en')
a = set(nlp('This is a test'))
b = nlp('is')
if b in a:
  print("Success")
else:
  print("Failed")

по какой-то причине этот вывод распечатан как "Failed". Я ожидал, что это удастся. Я новичок в использовании Spacy Framework, поэтому я не совсем уверен, как это сделать правильно. Как мне сделать это правильно?

Ответы [ 3 ]

0 голосов
/ 31 октября 2018

Я не думаю, что вы можете положиться на хэш токена для операции set Вы можете покопаться и посмотреть на атрибут .text

import spacy
nlp = spacy.load('en')
a = set(x.text for x in nlp('This is a test'))
b = nlp('is').text
if b in a:
  print("Success")
else:
  print("Failed")

доказательство ...

>>> import spacy
>>> nlp = spacy.load('en')
>>> a = set(x.text for x in nlp('This is a test'))
>>> b = nlp('is').text
>>> if b in a:
...   print("Success")
... else:
...   print("Failed")
... 
Success
0 голосов
/ 02 ноября 2018

@ bboyjacks: Спасибо, что ответили на этот интересный вопрос .

Я просто хочу сообщить вам, что это не относится конкретно к фреймворку spaCy, оно больше связано с концепциями python.

Ответ, предоставленный @John La Rooy выше, является правильным, но я поместил свою версию, как вы и то же, спрашивали и в сообществе spaCy (это может внести некоторую ясность в решение).

Пожалуйста, проверьте мой ответ ниже:

print(a) # prints -> {This, test, is}
print(b) # prints -> is

Так что, похоже, оператор 'in' должен работать, но выгода ниже:

print(type(a))          # prints -> <class 'set'>
print(type(a.pop()))    # prints -> <class 'spacy.tokens.token.Token'>
print(type(b))          # prints -> <class 'spacy.tokens.doc.Doc'>

Объект с типом [spacy.tokens.doc.Doc] == Объект с типом [spacy.tokens.token.Token] всегда возвращает ' False '

Нам нужно как-то преобразовать их в один и тот же тип, и, поскольку мы не уверены в том, что метод равенства, определенный в классах Token или Doc, предоставляемых spaCy, просто преобразует оба в класс str.

Это преобразование может быть выполнено, как показано выше @John La Rooy, или вы также можете попробовать выполнить полный код ниже.

import spacy
nlp = spacy.load('en')
a = set(nlp('This is a test'))
b = nlp('is')

if b.text in map(lambda token: token.text, a):
  print("Success")
else:
  print("Failed")

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

0 голосов
/ 31 октября 2018

type(b) - это <class 'spacy.tokens.doc.Doc'>, и вы сравниваете переменную с набором <class 'set'>. Поэтому попробуйте преобразовать обе переменные, чтобы установить, а затем попробуйте метод in. И каждый элемент в токенах nlp является классом <class 'spacy.tokens.token.Token'>, а не строкой. Поэтому вы должны преобразовать их в совместимые типы, прежде чем пытаться использовать оператор in.

a = set(nlp('This is a test'))
a = {str(token) for token in a} # convert all token type to str

b = nlp('is')
b = str(set(b).pop()) # convert token to str, effectively same as b = 'is'
if b in a:
  print("Success")
else:
  print("Failed")
...