Python用字典统计信息,python字典计数统计

  Python用字典统计信息,python字典计数统计

  索引引擎的基本工作原理是倒排索引,即一个文档中包含的文本依次映射到该文档;这个算法没有太多的猫腻。为了提高效率,可以将索引数据尽可能多地移入内存。

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

  doc_a:[word_w,word_x,word_y]

  doc_b:

  将它转换成

  word_w-[doc_a]

  word _ x-[文档_a,文档_b]

  word_y-[doc_a,doc_c]

  用Python代码写的Word_z-[doc_b]是

  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]}

  文档=[文档a,文档b,文档c]

  indices=dict()

  fordocindocs:

  forwordindoc[words]:

  ifwordnotinindices:

  indexes[word]=[]

  索引[单词]。追加(文档[id])

  Printindices但是这里有个小技巧,就是判断当前单词是否已经在索引字典的分支中。

  ifwordnotinindices:

  indexes[word]=[]可以用dict的setdefault(key,default=None)接口代替。这个接口的作用是,如果键在字典里,那么就这么说,并得出相应的值;否则,创建一个新的键,并将默认的相应值设置为default。但是从设计的角度来看,我不明白为什么default会有一个缺省值None,这似乎没有太大的意义。如果你真的想使用这个接口,它通常会自带默认值,如下所示

  fordocindocs:

  forwordindoc[words]:

  Indexes.setdefault (word,[])。追加(doc [id])。这就节省了分支,代码看起来也少了很多。

  但是,在某些情况下,setdefault并不好用。当缺省值结构复杂,或者缺省值有副作用,以及后面会讨论的一种情况;总之,前两种情况是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'])

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

  此外 collections 里还有个 Counter , 可以粗略认为它是 defaultdict(int) 的扩展.

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: