代码之家  ›  专栏  ›  技术社区  ›  Alex Bass

字行一致性程序

  •  1
  • Alex Bass  · 技术社区  · 8 年前

    我最初在这里发布了这个问题,但后来被告知将其发布到代码审阅;然而,他们告诉我,我的问题需要张贴在这里。我会尽力更好地解释我的问题,希望不会有任何混淆。我正在尝试编写一个word concordance程序,该程序将执行以下操作:

    1) 阅读stop\u单词。txt文件放入一个只包含停止词的字典(使用您正在计时的相同类型的字典),称为stopWordDict。(警告:在将停止字添加到stopWordDict之前,请先从停止字末尾删除换行符(\n))

    2) 处理战争与和平。txt文件一次一行,以构建单词一致性词典(称为wordConcordanceDict),其中包含键的–main–单词,并将其关联行号列表作为其值。

    3) 按键按字母顺序遍历单词concordancedict,生成一个文本文件,其中包含按字母顺序打印的一致单词及其相应的行号。

    我在一个小文件上测试了我的程序,该文件有一个简短的停止词列表,它工作正常(下面提供了一个示例)。结果是我所期望的,一个包含主要单词及其行数的列表,不包括stop\u words\u small中的单词。txt文件。我测试的小文件和我实际尝试测试的主文件之间的唯一区别是,主文件要长得多,并且包含标点符号。所以我遇到的问题是,当我用主文件运行程序时,我得到的结果比预期的要多。我之所以得到比预期更多的结果,是因为没有从文件中删除标点符号。

    例如,下面是结果的一部分,我的代码将单词Dmitri计算为四个单独的单词,因为单词后面的大小写和标点符号不同。如果我的代码正确删除标点符号,那么单词Dmitri将被计算为一个单词,后跟找到的所有位置。我的输出还分离了大写和小写单词,因此我的代码也没有将文件改为小写。

    我的代码当前显示的内容:

    Dmitri : [2528, 3674, 3687, 3694, 4641, 41131]
    
    Dmitri! : [16671, 16672]
    
    Dmitri, : [2530, 3676, 3685, 13160, 16247]
    
    dmitri : [2000]
    

    我的代码应该显示什么:

    dmitri : [2000, 2528, 2530, 3674, 3676, 3685, 3687, 3694, 4641, 13160, 16671, 16672, 41131]
    

    单词定义为由任何非字母分隔的字母序列。大写字母和小写字母之间也应该没有区别,但我的程序也会将它们分割开来;但是,空行应计入行号中。

    下面是我的代码,如果有人能看一下并给我任何关于我做错了什么的反馈,我将不胜感激。提前谢谢你。

    import re
    
    def main():
        stopFile = open("stop_words.txt","r")
        stopWordDict = dict()
    
        for line in stopFile:
            stopWordDict[line.lower().strip("\n")] = []
    
        hwFile = open("WarAndPeace.txt","r")
        wordConcordanceDict = dict()
        lineNum = 1
    
        for line in hwFile:
            wordList = re.split(" |\n|\.|\"|\)|\(", line)
            for word in wordList:
                word.strip(' ')
                if (len(word) != 0) and word.lower() not in stopWordDict:
                    if word in wordConcordanceDict:
                        wordConcordanceDict[word].append(lineNum)
                    else:
                        wordConcordanceDict[word] = [lineNum]
            lineNum = lineNum + 1
    
        for word in sorted(wordConcordanceDict):
            print (word," : ",wordConcordanceDict[word])
    
    
    if __name__ == "__main__":
    main()
    

    这里的另一个示例和参考是我测试的一个小文件,其中包含一小串非常有效的停止词。

    stop\u words\u small。txt文件

    a, about, be, by, can, do, i, in, is, it, of, on, the, this, to, was
    

    小型\u文件。txt文件

    This is a sample data (text) file to
    be processed by your word-concordance program.
    
    The real data file is much bigger.
    

    正确的输出

    bigger: 4
    
    concordance: 2
    
    data: 1 4
    
    file: 1 4
    
    much: 4
    
    processed: 2
    
    program: 2
    
    real: 4
    
    sample: 1
    
    text: 1
    
    word: 2
    
    your: 2
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Thierry Lathuille    8 年前

    您可以这样做:

    import re
    from collections import defaultdict
    
    wordConcordanceDict = defaultdict(list)
    
    with open('stop_words_small.txt') as sw:
        words = (line.strip() for line in sw)
        stop_words = set(words)
    
    with open('small_file.txt') as f:
        for line_number, line in enumerate(f, 1):
            words = (re.sub(r'[^\w\s]','',word).lower() for word in line.split())
            good_words = (word for word in words if word not in stop_words)
            for word in good_words:
                wordConcordanceDict[word].append(line_number)
    
    for word in sorted(wordConcordanceDict):
        print('{}: {}'.format(word, ' '.join(map(str, wordConcordanceDict[word]))))
    

    输出:

    bigger: 4
    data: 1 4
    file: 1 4
    much: 4
    processed: 2
    program: 2
    real: 4
    sample: 1
    text: 1
    wordconcordance: 2
    your: 2
    

    嫙嫙¼ ——明天我会补充解释,现在已经很晚了;)。同时,您可以在注释中询问代码的某些部分是否对您不清楚。