2016-06-14 7 views
2

я код вопрос:Почему функция NLTK wn.all_synsets() в wordnet возвращает список synsets?

Какой процент существительных synsets нет гипонимов? Вы можете получить все существительные synsets, используя wn.all_synsets ('n').

Вот мой код:

import nltk 
from nltk.corpus import wordnet as wn 

all_noun = wn.all_synsets('n') 
print(all_noun) 
print(wn.all_synsets('n')) 
all_num = len(set(all_noun)) 
noun_have_hypon = [word for word in wn.all_synsets('n') if len(word.hyponyms()) >= 1] 
noun_have_num = len(noun_have_hypon) 
print('There are %d nouns, and %d nouns without hyponyms, the percentage is %f' % 
    (all_num, noun_have_num, (all_num-noun_have_num)/all_num*100)) 

, когда я запускаю этот код, выход

<generator object all_synsets at 0x10927b1b0>

<generator object all_synsets at 0x10e6f0bd0>

Есть 82115 существительных и 16693 существительные без гипонимов, процент является 79.671193

но если изменение

noun_have_hypon = [word for word in wn.all_synsets('n') if len(word.hyponyms()) >= 1]

к

noun_have_hypon = [word for word in all_noun if len(word.hyponyms()) >= 1]

Выходной сигнал изменяется на

<generator object all_synsets at 0x10917b1b0>

<generator object all_synsets at 0x10e46aab0>

Есть 82115 существительные и 0 существительных без гипонимов, процент 100,000000

почему два ответа не равны, даже если all_noun = wn.all_synsets('n'), и в чем смысл 0x10927b1b0 & 0x10e6f0bd0 ?

+0

0x10927b1b0 & 0x10e6f0bd0 просто ячейки памяти, это просто означает, что любой объект 'wordnet.all_synets()' возвращение сделал не потрудитесь определить осмысленный метод '__str__'. – grochmal

+0

@grochmal, получил это! Thx !!!! –

ответ

2

Это имеет мало общего с NLTK, но больше разница между Generator Expressions vs. List Comprehension.

Давайте пройти через небольшой пример:

Во-первых, давайте создадим функцию, которая возвращает простой список:

>>> def some_func_that_returns_a_list(): 
...  list_to_be_returned = [] 
...  for i in range(10): 
...    list_to_be_returned.append(i) 
...  return list_to_be_returned 
... 
>>> some_func_that_returns_a_list() 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

Обратите внимание, что в функции some_func_that_returns_a_list(), список должен быть создан и ценности перед тем как функции вернутся к месту в коде, который его вызывает.

Аналогично можно использовать генератор для достижения того же списка, который должен быть возвращение, но это немного по-другому, так как он с помощью yield ключевого слова:

>>> def some_func_that_returns_a_generator(): 
...  for i in range(10): 
...    yield i 
... 
>>> 

Обратите внимание, что в функции нет конкретизации списка, который нужно вернуть.

И когда вы пытаетесь вызвать функцию:

>>>some_func_that_returns_a_generator() 
<generator object some_func_that_returns_a_generator at 0x7f312719a780> 

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

>>> import sys 
>>> sys.getsizeof(some_func_that_returns_a_generator()) 
80 
>>> sys.getsizeof(some_func_that_returns_a_list()) 
200 

Поскольку генератор не создать экземпляр значения результирующего списка вам нужно, это просто выскакивает элементы, которые являются yield по одному, вам нужно «вручную» перебрать генератор, чтобы получить список, например:

>>> list(some_func_that_returns_a_generator()) 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> [i for i in some_func_that_returns_a_generator()] 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

Но в данном случае, это создание списка «на -fly ", и если вы не собираетесь останавливать список, но для чтения элементов по одному, генератор будет полезен (память разумная).

Смотрите также:


Таким образом, в случае NLTK wn.all_synsets() WordNet API, вы можете просто сделать что-то вроде:

>>> from nltk.corpus import wordnet as wn 
>>> nouns_in_wordnet = list(wn.all_synsets('n')) 

Но обратите внимание, что он сохранит весь список синтаксисов, которые являются существительными в памяти.

И если вы хотите, чтобы отфильтровать существительных с более чем 1 hypernym, вы можете избежать инстанцировании полный список имен с помощью filter() функции:

>>> filter(lambda ss: len(ss.hypernyms()) > 0, wn.all_synsets('n')) 

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

>>> len(filter(lambda ss: len(ss.hypernyms()) > 0, wn.all_synsets('n'))) 
74389 

или менее пространно:

>>> sum(1 for ss in wn.all_synsets('n') if len(ss.hypernyms()) > 0) 
74389 

Но, скорее всего, вы хотели бы получить доступ к Synsets, так что вы могли бы искать:

>>> nouns_with_hyper = filter(lambda ss: len(ss.hypernyms()) > 0, wn.all_synsets('n')) 
>>> len(nouns_with_hyper) 
74389