拼写检查器---二十几行的Python代码写成的

简介:

这个代码是看了Peter大神的文章自己模仿这写的,基本就是copy人家的思路,不过自己在代码之间添加了一些注释。

How to Write a Spelling Corrector: http://norvig.com/spell-correct.html

自己写这个的目的是练习自己写Python代码的能力,而且在这个过程中确实收获还是蛮多的!

代码及其注释

# -*- coding: utf-8 -*-

import re
from collections import Counter

def words(text):
    return re.findall(r'\w+', text.lower())
    # findall函数作用(可查看用户手册)在这里就是用来将txt中的每一个单词进行分离,在返回一个字符串列表
        
WORDS = Counter(words(open('D:\\PythonWorkSpace\\big.txt').read()))
# 这里的WORDS就是一个无序的集合,里面存储的是K-V:K是单词,V是单词在txt中出现的次数。这个是由Count函数使得的

def P(word, N = sum(WORDS.values())):
    return WORDS[word] / N
    # P这个函数是用来计算word这个词在txt样本中出现的概率,当word没有出现过,WORDS[word]会返回0
        
def known(words):
# known这个函数返回一个集合,集合的内容是即在words这个集合中,又在WORDS中的单词
    return set(w for w in words if w in WORDS)
    
def edits1(word):
# edits1函数的作用是返回对word这个单词一次编辑后可能得到的所有结果的集合
    letters = 'abcdefghijklmnopqrstuvwxyz'
    splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]
    # splits 在这里就是由tuple组成的list,每一个tuple是word单词的分解形式
    # 这里面字符串索引得认真去研究一波,比如word[0:0]结果是空字符,word[aN:aN]结果也是很空字符
    deletes = [L + R[1:] for L, R in splits if R]
    # 这里面的R如果是空字符,就判断为False
    # deletes 在这里的作用就是得到word删掉一个字母的所有字符的集合
    transposes = [L + R[1] + R[0] + R[2:] for L, R in splits if len(R) > 1]
    # transposes 在这里的作用就是将word单词中任意两个字母调换一次位置后得到的所有单词的集合
    replaces = [L + c + R[1:] for L, R in splits if R for c in letters]
    # replaces 在这里的用途是将word单词中删掉一个字母后可能得到的单词的集合
    inserts = [L + c + R for L, R in splits for c in letters]
    # inserts 在此处的作用是插入一个字母到word单词中后可能得到的单词的集合
    return set(deletes + transposes + replaces + inserts)
        
def edits2(word):
# edits2函数的作用是返回对word这个单词进行两次编辑后可能得到的所有结果的集合
    return (e2 for e1 in edits1(word) for e2 in edits1(e1))
    
def candidates(word):
# candidates函数返回的内容:如果word在txt中出现过,则就返回word,如果没有的话,就返回对word编辑一次后获得的字符集中在txt中出现过的字符构成的集合,如果还是没有的话就返回二次编辑的,如果二次编辑的也没有的话,就返回word
# 看了写这个代码的人的解释,这个函数算是一个错误模型,用来保证所获得的结果是比较可信的
    return (known([word]) or known(edits1(word)) or known(edits2(word)) or [word])
    
def correction(word):
    return max(candidates(word), key = P)

下面一个代码是测试用的:

import sys
sys.path.append('D:\\PythonWorkSpace\\SpellingCheck.py')

import time
import SpellingCheck

def spelltest(tests, verbose = True):
    start = time.clock()
    good, unknown = 0, 0
    n = len(tests)
    for right, wrong in tests:
        w = SpellingCheck.correction(wrong)
        good += (w == right)
        if w != right:
            unknown += (right not in SpellingCheck.WORDS)
            if verbose:
                print('correction( {} ) => {} ( {} ); except {} ( {} )'.format(wrong, w, SpellingCheck.WORDS[w], right, SpellingCheck.WORDS[right]))
                
    dt = time.clock() - start
    
    print('{:.0%} of {} correct ({:.0%} unknown) at {:.0f} words per second'.format(good / n, n, unknown / n, n / dt))
    
def Testset(lines):
    return [(right, wrong) for (right, wrongs) in (line.split(':') for line in lines) for wrong in wrongs.split()]
    
spelltest(Testset(open('D:\\PythonWorkSpace\\spell-testset.txt')))    
说明

我将代码中测试的big.txt和spell-testset.txt放在D:\\PythonWorkSpace目录面

  • big.txt文件下载地址:http://norvig.com/big.txt

  • spell-testset.txt文件下载地址:http://norvig.com/spell-testset1.txt

总结

只能说自己的Python基础还是比较薄弱的,得加强!

转载于:https://my.oschina.net/QinghaiZheng/blog/848893

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值