【使用 Python 实现算法】目录
本期话题是 Python 的原生类型和内置函数在算法实现中的一些技巧,首先从最常见的 Python 原生类型开始。
int
int
类型有两个内置的方法bit_count
与bit_length
,分别用来获取整数二进制表达的1
的个数和二进制位数,在很多场景下都很实用。
1 | n = 9 |
float
float
的as_integer_ratio
方法可以获得浮点数的最简分数表达。
1 | f = 6.125 |
利用f-string
可以轻松获得浮点数的指定小数位数的字符串表达。
1 | assert f"{1/3:.4f}" == "0.3333" |
list
list
的pop
方法接收整数参数 n, 返回并删除列表中的第 n 个元素(O(n)的时间复杂度,效率不高)。
1 | arr = [1, 2, 3] |
算法实现中经常需要用到栈结构,Python 的 list
类型原生拥有栈的所有功能,也可以简单的封装一下,定义自己的 Stack
类型。
1 | class Stack(list): |
tuple
tuple
类型在算法实现中的使用频率不是很高,不过list
类型是不可哈希的(不能作为字典的键),这类场景下可以将list
转换为tuple
后进行使用。
dict
dict
的fromkeys
方法可以用于初始化拥有同一个默认值的字典。
1 | counter = dict.fromkeys("abc", 0) |
初始化dict
的另一个常用方法是使用字典推导式。
1 | counter = {ch: count for ch, count in [("a", 1), ("b", 2), ("c", 3)]} |
set
Python 的set
类型原生支持使用常见的运算符进行集合运算。
1 | a, b = set([1, 2, 3]), set([2, 3, 4]) |
str
有大量的算法题目涉及到字符串及其处理,Python 的str
类型拥有大量的用途多样的内置方法,主要分为三个类型。
检查字符串类型
1 | str.isalnum # 是否为字母或数字 |
根据内容返回新的字符串
1 | str.translate # 使用一个映射关系转换字符串 |
拆分为多个子串
1 | str.split # 使用指定分隔符拆分字符串 |
此外还有str.join
方法,可以用指定分隔符将多个字符串合并为一个。
complex
Python 原生提供复数类型complex
,并支持常见的算术运算。
1 | c = complex(1, -1) |
本期的第二部分的主题是 Python 的内置函数,并根据函数的参数类型和返回类型将内置函数分为对象类和容器(迭代器)类。
对象类
对象类的内置函数主要涉及具体类型的对象的处理。
abs
计算绝对值。
max, min
返回多个值(或一个可迭代对象)的最大值或最小值。
chr, ord
数字和 ASCII 字符的相互转换。
1 | chr(ord("a") + 1) == "b" |
divmod
同时获取整数除法运算的商和余数。
1 | assert divmod(5, 2) == (2, 1) |
hex
获取整数的十六进制表达。
1 | assert hex(255) == "0xff" |
pow
求幂。
1 | assert pow(2, 3) == 8 |
round
浮点数取整(四舍六入五成双)。
1 | assert round(1.2) == 1 |
容器、迭代器类
容器、迭代器类的内置函数用于处理和生成各类容器对象和迭代器对象。
all
所有元素为真值时返回True
1 | assert all(x < 10 for x in [1, 2, 3]) |
any
任一元素为真值时返回True
1 | assert any(x < 10 for x in [11, 9, 12]) |
next
获取可迭代对象的下一个元素,常用于获取收个满足条件的元素(为防止不存在符合条件的元素,可以跟一个兜底的值)。
1 | assert next(x for x in range(1, 10) if x % 3 == 0) == 3 |
enumerate
遍历容器,返回一个迭代索引和值的生成器(一般用在 for 循环中)。
1 | assert dict(enumerate("abc")) == {0: "a", 1: "b", 2: "c"} |
map
将指定函数应用到容器的每一个值,返回一个生成器(而不是列表)。
一般使用列表推导式替代map
函数,效率更高。
filter
使用指定函数测试容器的每一个值,过滤出函数值为真值的元素,返回一个生成器(而不是列表)。
range
获取可迭代的整数区间。
sum
获取容器或可迭代对象所有元素的和
sorted
对可迭代对象的值进行排序,返回一个列表,可指定排序方式,可返回倒序列表。
1 | assert sorted(range(10), key=lambda x: x % 3) == [0, 3, 6, 9, 1, 4, 7, 2, 5, 8] |
zip
传入多个可迭代对象,按顺序将每个参数的相同索引的元素组合为一个tuple
对象迭代生成。
1 | assert list(zip(range(4), "abcd")) == [(0, "a"), (1, "b"), (2, "c"), (3, "d")] |
可以使用 zip
方法进行矩阵转置。
1 | matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] |
总结
Python 的原生类型和内置函数是很强大,值得深入研究一下。