2019独角兽企业重金招聘Python工程师标准>>>

最近折腾索引引擎以及数据统计方面的工作比较多, 与 Python 字典频繁打交道, 至此整理一份此方面 API 的用法与坑法备案.
    索引引擎的基本工作原理便是倒排索引, 即将一个文档所包含的文字反过来映射至文档; 这方面算法并没有太多花样可言, 为了增加效率, 索引数据尽可往内存里面搬, 此法可效王献之习书法之势, 只要把十八台机器内存全部塞满, 那么基本也就功成名就了. 而基本思路举个简单例子, 现在有以下文档 (分词已经完成) 以及其包含的关键词

  • 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() for doc in docs: for word in doc['words']: if word not in indices: indices[word] = [] indices[word].append(doc['id']) print indices

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

if word not in indices: indices[word] = []

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

for doc in docs: for word in doc['words']: indices. setdefault(word, []) .append(doc['id'])

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

def setdefault(self, key, default_factory): if key not in self: self[key] = default_factory() return self[key]

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

for doc in docs: for word in doc['words']: indices.setdefault(word,  list ).append(doc['id'])

不过实际上有其它替代方案, 这个最后会提到.
    如果说上面只是一个能预见但实际上可能根本不会遇到的 API 缺陷, 那么下面这个就略打脸了.
    考虑现在要进行词频统计, 即一个词在文章中出现了多少次, 如果直接拿  dict  来写, 大致是

def word_count(words): count = dict() for word in words: count.setdefault(word, 0) += 1 return count print word_count(['hiiragi', 'kagami', 'hiiragi', 'tukasa', 'yosimizu', 'kagami'])

当你兴致勃勃地跑起上面代码时, 代码会以迅雷不及掩脸之势把异常甩到你鼻尖上 --- 因为出现在  +=  操作符左边的  count.setdefault(word, 0)  在 Python 中不是一个左值. 怎样, 现在开始念叨 C艹 类型体系的好了吧.
    因为 Python 把默认的字面常量  {}  等价于  dict()  就认为  dict  是银弹的思想是要不得的; Python 里面各种数据结构不少, 解决统计问题, 理想的方案是  collections.defaultdict  这个类. 下面的代码想必看一眼就明白

from collections import defaultdict 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) for doc in docs: for word in doc['words']: indices[word].append(doc['id']) print indices def word_count(words): count =  defaultdict(int) for word in words: count[word] += 1 return count print word_count(['hiiragi', 'kagami', 'hiiragi', 'tukasa', 'yosimizu', 'kagami'])

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

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

推荐阅读:

[1] 关于腾讯的一道字符串匹配的面试题

http://my.oschina.net/leejun2005/blog/78738

[2] 搜索引擎:该如何设计你的倒排索引?

http://mp.weixin.qq.com/s/aTMoiNPTatFLq2abLsGFiQ

转载于:https://my.oschina.net/leejun2005/blog/190213

倒排索引统计与 Python 字典相关推荐

  1. 【Python】Python字典的高级用法-统计计数

    在很多计算任务中,需要统计不同信息出现的次数,最常见的就是统计某段文字中每个词或者每个字出现的次数,也就是常见的词频统计,这个时候,字典就派上了很大的用场,我们看看通过字典怎么进行统计. 我们用鲁迅先 ...

  2. python字典统计_python字典计数

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 字典?thcollections.counter 计数器? image.png找 ...

  3. python字典统计单词个数_python字典统计单词个数

    python 字典中的词频统计之后 如何将频数大于一个比如a出现了10次,b15次,c20次,d25次,CSS布局HTML小编今天和大家分享频数大于14的词的个数,应该v={} for i in di ...

  4. Python字典简单实现词频统计

    目录 问题引入: 原理: 基本流程: 词频统计 ①录入待统计的句子 ②分割为多个单词 ③创建字典 利用Python内置库快速实现词频统计 全部代码 普通方法 方法二:get()实现 内置库实现 Pyt ...

  5. 这样合并Python字典,可以让程序的运行效率提高4倍

    摘要:在Python中,合并字典有多种方式,通过内建函数.运算符.自定义函数等,都可以完成合并字典的功能,但这些方式,哪些效率低,哪些效率高呢?本文将对这些合并字典的方式进行逐个深度详解,最后会比较这 ...

  6. 【Python基础】Python字典详解-超级完整版

    本文的目录: 一.字典概述 01 字典的格式 Python字典是一种可变容器模型,且可存储任意类型对象,如字符串.数字.元组等其他容器模型. 字典的每个键值key=>value对用冒号 : 分割 ...

  7. python字典求平均值_Python - 字典中各个键的每个值的均值

    我在跨整个字典进行迭代时遇到问题,无法对键的值中的每个元素进行简单的汇总统计(平均值).Python - 字典中各个键的每个值的均值 我的字典由那些号码清单键和值: test_dict={'NJ':[ ...

  8. 第九章 python 字典(Dict)

    第九章 python 字典(Dict) 9-1 字典基本操作 列表与元组是依序排列可称是序列数据结构,只要知道元素的特定位置,即可使用索引观念取得元素内容,这一章的重点是介绍了字典,它并不是依序排列的 ...

  9. python字典创建、使用字典保存中国主要城市和对应邮编_Python字典及相关操作(内含例题)...

    python字典类型 今天将会介绍一种在python中十分常见的组合数据类型--字典 通过一些实例来理解字典中的常规操作 什么是字典类型? 列表中查找是通过整数的索引(元素在列表中的序号)来实现查找功 ...

最新文章

  1. android采用MVP完整漫画APP、钉钉地图效果、功能完善的音乐播放器、仿QQ动态登录效果、触手app主页等源码...
  2. 寒武纪上市:AI芯片和普通芯片有何不同?全球AI芯片公司大全都在这里了
  3. 高仿书旗小说 Flutter版,支持iOS、Android
  4. 剑网三缘起,葱姜蒜也能卖?欺负新玩家被批评,但说明游戏很自由
  5. Linux系统编程20:基础IO之从内核代码深刻理解Linux是如何管理文件及文件描述符的本质是什么
  6. 我的世界末日求生系列服务器,末日生存 少年pi
  7. iptables实现NAT
  8. Mysql的数据库引擎 区别特点_mysql数据库存储引擎及区别
  9. Iphone 视图跳转方法总结
  10. 连续两天,8 大技术论坛,微软超 60 个烧脑议题等你来战
  11. android 资源改名,安卓已经安装完的软件怎么改名?
  12. #ardiuno #蓝牙 #if函数判断 #串口中米思齐
  13. 创客集结号:3D打印技术的FDM技术与SLA技术
  14. php微信公众号发送多条消息模板,整合ThinkPHP功能系列之微信公众号模板消息发送...
  15. Sparten6/Kintex-7 DDR3 IP仿真实例
  16. 电驱系列:直流无刷马达(不用芯片,独立元器件搭建)
  17. openwrt web框架luci简介,20行代码写一个前后端交互页面
  18. 如何使用python做图_如何使用python做动图
  19. 终极单词index 排序 C-D
  20. Raw Socket和Socket编程

热门文章

  1. 甚长基线干涉测量技术(VLBI)基础
  2. 总结C#保留小数位数
  3. 一致的数据访问技术ADO/OLE DB
  4. MySQL检查冗余索引代码
  5. 通过js引入当前所需要的js,css等
  6. 简单几步解决企业USB端口隐患
  7. php 正则表达式界限符
  8. Kubernetes Ingress 日志分析与监控的最佳实践
  9. 【教程】Matrikon OPC使用教程连载(四)
  10. 使用Spring操作Redis的key-value数据