说说在 Python 中如何使用 setDefault 方法提高效率

uciano Ramalho 举了一个示例来说明 setDefault 方法相对于传统写法的高效性 1 。

import sys
import re

WORD_RE = re.compile(r'\w+')

index = {}
with open(sys.argv[1], encoding='utf-8') as fp:
    for line_no, line in enumerate(fp, 1):
        for match in WORD_RE.finditer(line):
            word = match.group()
            column_no = match.start() + 1
            location = (line_no, column_no)

            occurrences = index.get(word, [])
            occurrences.append(location)
            index[word] = occurrences

for word in sorted(index, key=str.upper):
    print(word, index[word])

多人学习python,不知道从何学起。

很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。

很多已经做案例的人,却不知道如何去学习更加高深的知识。

那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!??¤

QQ群:1057034340

运行结果:

a [(1, 7), (1, 46), (1, 76), (1, 111), (3, 52), (3, 87), (19, 75), (19, 162)]
about [(9, 83)]
acknowledged [(1, 27)]
agreed [(19, 241)]
all [(9, 79)]
and [(9, 63), (15, 23), (19, 171), (19, 198), (19, 326)]
……
(1)enumerate() 函数

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标。 语法: enumerate(sequence, [start=0])

参数名说明
sequence序列、迭代器或其他支持迭代的对象
start下标起始位置
enumerate /ɪˈnuːməreɪt/

To count off or name one by one; list

因为入参是一篇文章,所以示例中的 enumerate 方法的 start 从 1 开始,即表示第一行。

(2)正则 finditer() 方法

finditer() 方法会返回一个MatchObject 类型的iterator 2 ,所以需要一个个遍历。相比于 findall() 方法,使用 finditer() 方法可以省去外层所包裹的括号。

示例中使用 finditer() 方法来查找每一行中的单词。column_no 表示单词所在的列索引。location 是一个包含行索引与列索引的元组,本质上是单词所在的坐标。

(3)get() 方法设置默认值

index 存放的是字典,key 为单词,值为单词在这篇文章中所出现的坐标列表。这里利用 python 字典的 get() 方法的第二个入参来指定默认值。语法为: dict.get(key, default=None) 3 。

如果单词 key 已经在字典中存在,则返回列表,否则返回一个空列表。然后把当然所确定的单词坐标放入该列表。

(4)排序

最后按照单词字母顺序打印出字典中的单词坐标列表。因为使用了 sorted 函数的 key=str.upper 属性,所以不分大小写, key=str.lower 效果与 key=str.upper 相同。key 用来指定元素的比较规则 4 。

2 优化

其实以下三行我们可以利用 setDefault 方法在一行中实现:

occurrences = index.get(word, [])
occurrences.append(location)
index[word] = occurrences
复制代码

优化后:

index.setdefault(word, []).append(location)
复制代码

传递给 setdefault 方法的第一个参数是要检查的键。第二个参数需要设置的默认值。如果该键存在,该方法会直接返回键所对应的值 5 。

这样写的好处是:

  1. 代码简洁;
  2. 原来的示例需要查询两次。第一次是 index.get() 找出单词坐标列表;第二次是 index[word] 。优化后只需一次查询,因此提升了性能。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值