Это имеет мало общего с 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
0x10927b1b0 & 0x10e6f0bd0 просто ячейки памяти, это просто означает, что любой объект 'wordnet.all_synets()' возвращение сделал не потрудитесь определить осмысленный метод '__str__'. – grochmal
@grochmal, получил это! Thx !!!! –