#python #string #list #dictionary
#python #строка #Список #словарь
Вопрос:
У меня есть список строк следующим образом :
list_of_words = ['all saints church','churchill college', "great saint mary's church", 'holy trinity church', "little saint mary's church", 'emmanuel college']
И у меня есть список словарей, который содержит «текст» в качестве ключа и предложение в качестве значения. Это выглядит следующим образом :
"dict_sentences": [
{
"text": "Can you help me book a taxi going from emmanuel college to churchill college?"
},
{
"text": "Yes, I could! What time would you like to depart from Emmanuel College?"
},
{
"text": "I want a taxi to holy trinity church"
},
{
"text": "Alright! I have a yellow Lexus booked to pick you up. The Contact number is 07543493643. Anything else I can help with?"
},
{
"text": "No, that is everything I needed. Thank you!"
},
{
"text": "Thank you! Have a great day!"
}
]
Для каждого предложения в dict_sentences я хочу проверить, существует ли в этом предложении какое-либо из слов из list_of_words, и если да, я хочу сохранить его в другом словаре (так как мне нужно еще поработать над ним).
Например, в первом предложении в dict_sentences: «Не могли бы вы помочь мне заказать такси, идущее от колледжа Эммануэля до колледжа Черчилля?«, подстрока «колледж Черчилля» и «колледж Эммануэля» существует в нашем list_of_words, поэтому я хочу сохранить слова «колледж Черчилля» и «колледж Эммануэля» в другом словаре, например { sent1 : ['churchill college', 'emmanuel college'] }
Таким образом, ожидаемый результат будет :
{ sent1 : ['churchill college', 'emmanuel college'] ,
sent2 : [ 'emmanuel college' ],
sent3 : [ 'holy trinity church' ]
} # ignore the rest of sentences as no word from list_of_words exist in them
Основная проблема здесь заключается в проверке, состоит ли данное предложение из слова / группы слов (например, «церковь святой Троицы» — 3 слова) в данном предложении, и если да, извлекает то же самое. Я просмотрел другие ответы, и был предложен следующий код для проверки, встречается ли слово из списка в предложении :
if any(word in sentence for word in list_of_words()):
pass
Однако таким образом мы можем только проверить, существует ли слово из предложения в list_of_words() , чтобы извлечь слово, мне придется запускать циклы for . Но я воздерживаюсь от использования циклов for, поскольку мне нужно очень экономичное по времени решение, потому что у меня около 300 документов, где каждый документ состоит из таких 10-15 (или более) предложений, а list_of_words слишком велик, т.Е. около 300 строк. Итак, мне нужен эффективный по времени способ проверки и извлечения слова из заданного предложения, которое существует в list_of_words .
Комментарии:
1. Исходя из того, что вам нужно, не думайте, что у вас есть выбор, кроме как перебирать весь список. Что вы можете попробовать, так это сначала сжать ваши документы, проверив, появляется ли какое-либо из них первым.
Ответ №1:
Вы могли бы использовать re.findall
so, чтобы не было вложенного цикла.
output = {}
find_words = re.compile('|'.join(list_of_words)).findall
for i, (s,) in enumerate(map(dict.values, data['dict_sentences']), 1):
words = find_words(s.lower())
if words:
output[f"sent{i}"] = words
{'sent1': ['emmanuel college', 'churchill college'],
'sent2': ['emmanuel college'],
'sent3': ['holy trinity church']}
Это также можно сделать в dict_comprehension, используя оператор walrus в python 3.8 , хотя это может быть немного чрезмерно:
find_sent = re.compile('|'.join(list_of_words)).findall
iter_sent = enumerate(map(dict.values, data['dict_sentences']), 1)
output = {f"sent{i}": words for i, (s,) in iter_sent if (words := find_sent(s.lower()))}
Ответ №2:
Может быть более эффективный способ сделать это с помощью чего-то вроде itertools
, но я не очень хорошо знаком с ним.
test = {"dict_sentences":...} # I'm assuming it's a section of a json or a larger dictionary.
output = {}
j = 1
for sent in test["dict_sentences"]:
addition = []
for i in list_of_words:
if i.upper() in sent["text"].upper():
addition.append(i)
if addition:
output[f"sent{j}"] = addition
j = 1
Ответ №3:
Вы можете выполнить понимание вложенного dict и сравнить содержимое, преобразовав оба в нижний регистр, например:
output = {
f"sent{i 1}": [
phrase for phrase in list_of_words if phrase.lower() in sentence['text'].lower()
] for i,sentence in enumerate(dict_sentences)
}
output_without_empty_matches = { k:v for k,v in output.items() if v }
print(output_without_empty_matches)
>>> {'sent1': ['churchill college', 'emmanuel college'], 'sent2': ['emmanuel college'], 'sent3': ['holy trinity church']}
Ответ №4:
new_list=[]
new_dict={}
for index, subdict in enumerate(dict_sentences):
for word in list_of_words:
if word in subdict['text'].lower():
key="sent" str(index 1)
new_list.append(word)
new_dict[key]=new_list
new_list=[]
print(new_dict)