#python #nested #tuples
#python #вложенный #кортежи
Вопрос:
У меня есть список кортежей, который выглядит следующим образом :
[(('review', 'shop', 'draw'), 35),
(('shop', 'drawing', 'review'), 32),
(('field', 'review', 'report'), 24),
(('review', 'shop', 'drawing'), 20),
(('shop', 'drawing', 'return'), 20),
(('shop', 'draw', 'review'), 18),
(('site', 'review', 'report'), 17),
(('respond', 'rfi', 'regard'), 15),
(('review', 'fire', 'alarm'), 11),
(('review', 'lighting', 'shop'), 10)]
и я хотел бы объединить те элементы, которые похожи, после их определения вместе с их количеством:
from nltk.stem import PorterStemmer
for elm in trigram_counts:
ngrams = list(elm[0])
stemmed_ngrams = []
for gram in ngrams:
stemmed_ngrams.append(porter.stem(gram))
print(stemmed_ngrams, elm[1])
это дает что-то вроде этого :
['review', 'shop', 'draw'] 35
['shop', 'draw', 'review'] 32
['field', 'review', 'report'] 24
['review', 'shop', 'draw'] 20
['shop', 'draw', 'return'] 20
['shop', 'draw', 'review'] 18
['site', 'review', 'report'] 17
['respond', 'rfi', 'regard'] 15
['review', 'fire', 'alarm'] 11
['review', 'light', 'shop'] 10
Моя цель — объединить, например ['review', 'shop', 'draw']
, и ['shop', 'draw', 'review']
с их соответствующей суммой, которая равна 67
Я думаю, что усложняю это своим решением, перебирая все элементы.
Комментарии:
1. Является
trigram_counts
ли переменная, которая содержит ваш список кортежей?2. Каков критерий для подобных? Что кортеж содержит одинаковые (три) строки, а порядок не имеет значения? Что, если кортеж есть
('review', 'shop', 'draw', 'fire')
, а другой кортеж есть('review', 'shop', 'draw')
; они похожи?3. Я бы использовал словарь с
set(inner_tuple)
его ключом.4. Вместо добавления в a
list
, добавьте в aset
. Затем преобразуйте набор в atuple
, используйте вtuple
качестве ключа к adict
, значения которого представляют собой текущую сумму, которую вы хотите для этого набора5. Вы можете отсортировать кортеж, чтобы сравнить их на равенство.
Ответ №1:
Поскольку вы хотите объединить подсчеты из похожих базовых триграмм, вы можете использовать словарь с frozensets в качестве ключей: ключами будут базовые триграммы, а значениями — общее количество.
Вы должны использовать frozensets вместо наборов в качестве ключей, поскольку ключи dict должны быть хешируемыми (что не относится к наборам).
У вас будет что-то вроде этого:
from collections import defaultdict
from nltk.stem import PorterStemmer
stemmed_trigram_counts = defaultdict(int) # use defaultdict to avoid to have to check if the key exist
porter = PorterStemmer()
for trigram, count in trigram_counts:
stemmed_trigram = frozenset(porter.stem(word) for word in trigram)
stemmed_trigram_counts[stemmed_trigram] = count
print(stemmed_trigram_counts)
Это даст вам следующий результат:
{
frozenset({'draw', 'review', 'shop'}): 105,
frozenset({'field', 'report', 'review'}): 24,
frozenset({'draw', 'return', 'shop'}): 20,
frozenset({'report', 'review', 'site'}): 17,
frozenset({'regard', 'respond', 'rfi'}): 15,
frozenset({'alarm', 'fire', 'review'}): 11,
frozenset({'light', 'review', 'shop'}): 10
}
Примечание: в случае, если порядок имеет значение, вы должны использовать кортежи вместо замороженных наборов