首页IT科技python 字典sorted(巧用Python字典处理索引统计)

python 字典sorted(巧用Python字典处理索引统计)

时间2025-05-04 06:57:04分类IT科技浏览3506
导读:索引引擎的基本工作原理便是倒排索引, 即将一个文档所包含的文字反过来映射至文档; 这方面算法并没有太多花样可言, 为了增加效率, 索引数据尽可往内存里面搬。...

索引引擎的基本工作原理便是倒排索引, 即将一个文档所包含的文字反过来映射至文档; 这方面算法并没有太多花样可言, 为了增加效率, 索引数据尽可往内存里面搬         。

而基本思路举个简单例子, 现在有以下文档 (分词已经完成) 以及其包含的关键词:

doc_a:[word_w,word_x,word_y] doc_b:[word_x,word_z] doc_c:[word_y]

将其变换为

word_w->[doc_a] word_x->[doc_a,doc_b] word_y->[doc_a,doc_c] word_z->[doc_b]

写成 Python 代码, 便是

doc_a={id:a,words:[word_w,word_x,word_y]} doc_b={id:b,words:[word_x,word_z]} doc_c={id:c,words:[word_y]} docs=[doc_a,doc_b,doc_c] indices=dict() fordocindocs: forwordindoc[words]: ifwordnotinindices: indices[word]=[] indices[word].append(doc[id]) printindices

不过这里有个小技巧, 就是对于判断当前词是否已经在索引字典里的分支

ifwordnotinindices: indices[word]=[]

可以被 dict 的 setdefault(key, default=None) 接口替换. 此接口的作用是, 如果 key 在字典里, 那么好说, 拿出对应的值来; 否则, 新建此 key , 且设置默认对应值为 default . 但从设计上来说, 我不明白为何 default 有个默认值 None , 看起来并无多大意义, 如果确要使用此接口, 大体都会自带默认值吧, 如下

fordocindocs: forwordindoc[words]: indices.setdefault(word,[]).append(doc[id])

这样就省掉分支了, 代码看起来少很多.

不过在某些情况下, setdefault 用起来并不顺手: 当 default 值构造很复杂时, 或产生 default 值有副作用时, 以及一个之后会说到的情况; 前两种情况一言以蔽之, 就是 setdefault 不适用于 default 需要惰性求值的场景. 换言之, 为了兼顾这种需求, setdefault 可能会设计成

defsetdefault(self,key,default_factory): ifkeynotinself: self[key]=default_factory() returnself[key]

倘若真如此, 那么上面的代码应改成

fordocindocs: forwordindoc[words]: indices.setdefault(word,list).append(doc[id])

不过实际上有其它替代方案, 这个最后会提到.

如果说上面只是一个能预见但实际上可能根本不会遇到的 API 缺陷, 那么下面这个就略打脸了.

考虑现在要进行词频统计, 即一个词在文章中出现了多少次, 如果直接拿 dict 来写, 大致是

defword_count(words): count=dict() forwordinwords: count.setdefault(word,0)+=1 returncount printword_count([hiiragi,kagami,hiiragi,tukasa,yosimizu,kagami])

当你兴致勃勃地跑起上面代码时, 代码会以迅雷不及掩脸之势把异常甩到你鼻尖上 --- 因为出现在 += 操作符左边的 count.setdefault(word, 0) 在 Python 中不是一个左值. 怎样, 现在开始念叨 C艹 类型体系的好了吧.

因为 Python 把默认的字面常量 {} 等价于 dict() 就认为 dict 是银弹的思想是要不得的; Python 里面各种数据结构不少, 解决统计问题, 理想的方案是 collections.defaultdict 这个类. 下面的代码想必看一眼就明白

fromcollectionsimportdefaultdict doc_a={id:a,words:[word_w,word_x,word_y]} doc_b={id:b,words:[word_x,word_z]} doc_c={id:c,words:[word_y]} docs=[doc_a,doc_b,doc_c] indices=defaultdict(list) fordocindocs: forwordindoc[words]: indices[word].append(doc[id]) printindices defword_count(words): count=defaultdict(int) forwordinwords: count[word]+=1 returncount printword_count([hiiragi,kagami,hiiragi,tukasa,yosimizu,kagami])

完满解决了之前遇到的那些破事.

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
python 验证码生成(Python脚本绘制验证码) python子线程退出(Python中的子进程是什么)