检查两个字符串在Python中是否包含相同的单词集

The*_*der 5 python text text-extraction python-2.7

我正在尝试比较两个句子,看看它们是否包含相同的单词集。
例如:比较“今天是美好的一天”和“今天是美好的一天”应该返回true
我现在正在使用来自集合模块的Counter函数

from collections import Counter


vocab = {}
for line in file_ob:
    flag = 0
    for sentence in vocab:
        if Counter(sentence.split(" ")) == Counter(line.split(" ")):
            vocab[sentence]+=1
            flag = 1
            break
        if flag==0:
            vocab[line]=1
Run Code Online (Sandbox Code Playgroud)

它似乎可以正常工作几行,但是我的文本文件有1000多个,并且从未完成执行。还有其他方法,更有效的方法可以帮助我计算整个文件的结果吗?

编辑:

我只需要替换Counter方法,就可以替换它。而且实施上没有任何变化。

Eri*_*nil 3

您确实不需要使用两个循环。

字典的正确使用方法

假设您有dict

my_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 5, 'g': 6}
Run Code Online (Sandbox Code Playgroud)

您的代码基本上相当于:

for (key, value) in my_dict.items():
    if key == 'c':
        print(value)
        break
#=> 3
Run Code Online (Sandbox Code Playgroud)

dict但(and set, , ...)的重点Counter是能够直接获得所需的值:

my_dict['c']
#=> 3
Run Code Online (Sandbox Code Playgroud)

如果您的字典有 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})
Run Code Online (Sandbox Code Playgroud)

甚至更短:

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})
Run Code Online (Sandbox Code Playgroud)

这段代码应该比您到目前为止所尝试的要快得多。

还有另一种选择

如果你想将原始句子保留在列表中,你可以使用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']}
Run Code Online (Sandbox Code Playgroud)