Частота и следующие слова для слова из списка биграмм на python

#python

Вопрос:

У меня есть это предложение: 'Johnny Johnny yes papa' , и я хочу рассчитать частоту следующего слова для каждого слова. В этом случае я превращаю предложение в круговое:

 sentence = 'Johnny Johnny yes papa'
sentence = sentence.split()
sentence.append(sentence[0])
 

Теперь приговор таков ['Johnny','Johnny','yes','papa','Johnny']

Я создаю биграммы таким образом:

 def to_bigrams(my_list):
  bigrams = [(my_list[i],my_list[i 1]) for i,element in enumerate(my_list) if i<len(my_list)-1]
  return bigrams

my_bigrams = to_bigrams(sentence)
 

И теперь мои биграммы: [('Johnny', 'Johnny'), ('Johnny', 'yes'), ('yes', 'papa'), ('papa', 'Johnny')]

Теперь , например Johnny , есть два результата: Johnny и yes , и yes имеет только один результат, который является papa и papa имеет только один результат, Johnny поэтому ожидаемый словарь:

 {'Johnny':['Johnny','yes'],'yes':['papa'],'papa':['Johnny']}
 

Я уже пробовал это:

 my_freq_dict = {my_bigrams[i][0]:my_bigrams[i][j] for i,element in enumerate(my_bigrams) for j in range(len(my_bigrams))}
 

Но я получаю эту ошибку: IndexError: tuple index out of range . Что-то не так с моей логикой, пожалуйста, не могли бы вы мне помочь?

Ответ №1:

Один из способов использования dict.setdefault :

 my_bigrams = [('Johnny', 'Johnny'), ('Johnny', 'yes'), ('yes', 'papa'), ('papa', 'Johnny')]

d = {}
for v1, v2 in my_bigrams:
    d.setdefault(v1, []).append(v2)
d
 

Выход:

 {'Johnny': ['Johnny', 'yes'], 'yes': ['papa'], 'papa': ['Johnny']}
 

Ваша попытка создает ошибку, потому что вы используете len(my_bigrams) вместо len(element) .

Исправление этого, однако, не приведет к ожидаемому результату, так как некоторые ключи появляются более одного раза и, следовательно, будут перезаписаны последней записью (что dict и должно быть сделано).

Комментарии:

1. У меня возникла идея, что если значения нет, то по умолчанию у вас пустой список, а затем вы добавляете второй член кортежей! Большое вам спасибо @Крис, я ценю ваше время за то, что вы объяснили мою ошибку и дали ответ.

Ответ №2:

Вы можете использовать itertools.groupby

 from itertools import groupby

res = {key: [x[1] for x in group]for key, group in groupby(sorted(data, key=lambda x: x[0]), key= lambda x: x[0])}
print(res)
 

Выход:

 {'Johnny': ['Johnny', 'yes'], 'yes': ['papa'], 'papa': ['Johnny']}
 

Комментарии:

1. Спасибо за ответ @deadshot, интересное использование словаря понимания