你真的不需要使用两个循环。
正确使用字典的方法
假设你有一个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']}