Вам действительно не нужно использовать две петли.
Правильный способ использования диктов
Допустим, у вас есть dict
:
my_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 5, 'g': 6}
Вашкод в основном эквивалентен:
for (key, value) in my_dict.items():
if key == 'c':
print(value)
break
#=> 3
Но весь смысл dict
(и set
, Counter
, ...) в том, чтобы иметь возможность напрямую получить желаемое значение:
my_dict['c']
#=> 3
Если ваш dict имеет 1000 значений, первый пример будет в среднем в 500 раз медленнее, чем второй.Вот простое описание, которое я нашел на Reddit :
Диктовка похожа на комнату проверки волшебного пальто.Вы передаете свое пальто и получаете билет.Всякий раз, когда вы отдаете этот билет, вы немедленно получаете свое пальто.У вас может быть много пальто, но вы все равно получите его обратно сразу.Внутри комнаты проверки шерсти происходит много магии, но вам все равно, если вы сразу же вернете свое пальто.
Рефакторированный код
Вы простонужно найти общую подпись между "Today is a good day!"
и "Is today a good day?"
.Один из способов - извлечь слова, преобразовать их в строчные, отсортировать и объединить.Важно то, что вывод должен быть неизменным (например, tuple
, string
, frozenset
).Таким образом, его можно использовать внутри наборов, счетчиков или диктов напрямую , без необходимости перебирать каждый ключ.
from collections import Counter
sentences = ["Today is a good day", 'a b c', 'a a b c', 'c b a', "Is today a good day"]
vocab = Counter()
for sentence in sentences:
sorted_words = ' '.join(sorted(sentence.lower().split(" ")))
vocab[sorted_words] += 1
vocab
#=> # Counter({'a day good is today': 2, 'a b c': 2, 'a a b c': 1})
или даже короче:
from collections import Counter
sentences = ["Today is a good day", 'a b c', 'a a b c', 'c b a', "Is today a good day"]
def sorted_words(sentence):
return ' '.join(sorted(sentence.lower().split(" ")))
vocab = Counter(sorted_words(sentence) for sentence in sentences)
# Counter({'a day good is today': 2, 'a b c': 2, 'a a b c': 1})
Этот код должен быть намного быстрее того, что вы пробовали до сих пор.
Еще одна альтернатива
Если вы хотите сохранить оригинальные предложения в списке, вы можете использовать setdefault
:
sentences = ["Today is a good day", 'a b c', 'a a b c', 'c b a', "Is today a good day"]
def sorted_words(sentence):
return ' '.join(sorted(sentence.lower().split(" ")))
vocab = {}
for sentence in sentences:
vocab.setdefault(sorted_words(sentence), []).append(sentence)
vocab
#=> {'a day good is today': ['Today is a good day', 'Is today a good day'],
# 'a b c': ['a b c', 'c b a'],
# 'a a b c': ['a a b c']}