16 - 常用内置函数与标准库Python 自带了很多好用的函数和模块这章挑最实用的讲。不用全记住知道有这些东西需要的时候回来查就行。常用内置函数数学相关# abs() — 绝对值print(abs(-5))# 5# round() — 四舍五入print(round(3.7))# 4print(round(3.14159,2))# 3.14# max() / min() — 最大值/最小值print(max(3,1,4,1,5))# 5print(min([3,1,4]))# 1# sum() — 求和print(sum([1,2,3,4,5]))# 15print(sum([1,2,3],10))# 1610 是起始值# pow() — 幂运算print(pow(2,10))# 1024print(pow(2,10,100))# 242^10 % 100# divmod() — 同时得到商和余数q,rdivmod(17,5)print(q,r)# 3 2类型转换int(42)# 字符串转整数float(3.14)# 字符串转浮点数str(42)# 数字转字符串bool(0)# 转布尔值list(abc)# [a, b, c]tuple([1,2,3])# (1, 2, 3)set([1,1,2])# {1, 2}dict(a1,b2)# {a: 1, b: 2}序列操作# len() — 长度print(len([1,2,3]))# 3print(len(hello))# 5# sorted() — 排序返回新列表print(sorted([3,1,4,1,5]))# [1, 1, 3, 4, 5]print(sorted(python))# [h, n, o, p, t, y]# 自定义排序words[banana,apple,cherry]print(sorted(words,keylen))# [apple, banana, cherry]# reversed() — 反转返回迭代器print(list(reversed([1,2,3])))# [3, 2, 1]# range() — 数字序列print(list(range(5)))# [0, 1, 2, 3, 4]print(list(range(1,10,2)))# [1, 3, 5, 7, 9]map、filter、zip# map() — 对每个元素应用函数numbers[1,2,3,4,5]squareslist(map(lambdax:x**2,numbers))print(squares)# [1, 4, 9, 16, 25]# 等价的列表推导式更推荐squares[x**2forxinnumbers]# filter() — 过滤元素evenslist(filter(lambdax:x%20,numbers))print(evens)# [2, 4]# 等价的列表推导式evens[xforxinnumbersifx%20]# zip() — 配对names[小明,小红]ages[25,22]print(list(zip(names,ages)))# [(小明, 25), (小红, 22)]# zip 创建字典ddict(zip(names,ages))print(d)# {小明: 25, 小红: 22}map和filter在 Python 里用得没有 JavaScript 那么多因为列表推导式通常更清晰。但认识它们很重要读别人的代码时会遇到。any 和 all# any() — 有一个 True 就是 Trueprint(any([False,False,True]))# Trueprint(any([0,,None]))# False# all() — 全部 True 才是 Trueprint(all([True,True,True]))# Trueprint(all([True,False,True]))# Falseprint(all([]))# True空序列返回 True# 实际用法numbers[2,4,6,8]print(all(n%20forninnumbers))# True全是偶数words[hello,world,python]print(any(len(w)5forwinwords))# True有长度超过5的enumeratefruits[苹果,香蕉,橘子]fori,fruitinenumerate(fruits):print(f{i}:{fruit})# 指定起始索引fori,fruitinenumerate(fruits,start1):print(f第{i}个:{fruit})常用标准库os — 操作系统交互importos# 当前工作目录print(os.getcwd())# 环境变量print(os.environ.get(HOME))print(os.getenv(PATH,未设置))# 执行系统命令不推荐用 os.system用 subprocessimportsubprocess resultsubprocess.run([ls,-l],capture_outputTrue,textTrue)print(result.stdout)sys — 系统相关importsysprint(sys.version)# Python 版本print(sys.platform)# 平台linux/darwin/win32print(sys.argv)# 命令行参数print(sys.path)# 模块搜索路径# 退出程序# sys.exit(0) # 正常退出# sys.exit(1) # 异常退出datetime — 日期时间fromdatetimeimportdatetime,date,timedelta# 当前时间nowdatetime.now()print(now)# 2024-05-25 14:30:00.123456print(now.strftime(%Y-%m-%d %H:%M:%S))# 格式化# 创建指定时间dtdatetime(2024,1,15,10,30)# 时间差tomorrownowtimedelta(days1)last_weeknow-timedelta(weeks1)# 时间比较print(tomorrownow)# True# 解析字符串dtdatetime.strptime(2024-05-25,%Y-%m-%d)# 只用日期todaydate.today()print(today)# 2024-05-25random — 随机数importrandom# 随机整数print(random.randint(1,100))# 随机浮点数print(random.random())# 0-1 之间print(random.uniform(1,10))# 1-10 之间# 随机选择fruits[苹果,香蕉,橘子]print(random.choice(fruits))# 随机选一个print(random.sample(fruits,2))# 随机选两个不重复# 打乱顺序numbers[1,2,3,4,5]random.shuffle(numbers)print(numbers)# 比如 [3, 1, 5, 2, 4]collections — 高效数据结构前面已经讲过defaultdict和Counter这里补充几个fromcollectionsimportdeque,OrderedDict# deque — 双端队列两头都能快速增删ddeque([1,2,3])d.appendleft(0)# 左边加d.append(4)# 右边加d.popleft()# 左边删print(d)# deque([1, 2, 3, 4])# 限制最大长度滑动窗口ddeque(maxlen3)d.append(1)d.append(2)d.append(3)d.append(4)# 1 被自动挤掉print(d)# deque([2, 3, 4], maxlen3)# OrderedDict — 有序字典Python 3.7 普通 dict 也有序了用得少了itertools — 迭代器工具fromitertoolsimportchain,product,combinations,groupby# chain — 把多个可迭代对象连起来forxinchain([1,2],[3,4],[5]):print(x)# 1 2 3 4 5# product — 笛卡尔积forx,yinproduct(AB,12):print(x,y)# A1 A2 B1 B2# combinations — 组合forcomboincombinations(ABCD,2):print(combo)# (A,B) (A,C) (A,D) (B,C) (B,D) (C,D)# groupby — 分组数据需要先排序data[(A班,小明),(A班,小红),(B班,小刚)]data.sort(keylambdax:x[0])# 必须先排序forkey,groupingroupby(data,keylambdax:x[0]):print(f{key}:{list(group)})functools — 函数工具fromfunctoolsimportreduce,lru_cache# reduce — 累积计算fromfunctoolsimportreduceresultreduce(lambdaa,b:ab,[1,2,3,4,5])print(result)# 15((((12)3)4)5)# lru_cache — 函数缓存缓存装饰器lru_cache(maxsize128)deffibonacci(n):ifn2:returnnreturnfibonacci(n-1)fibonacci(n-2)print(fibonacci(100))# 瞬间算出来没缓存的话会慢得要死lru_cache是个很实用的装饰器能缓存函数的计算结果。对于递归或者重复计算的场景性能提升巨大。pathlib — 路径处理第 12 章已经讲过了这里简单回顾frompathlibimportPath pPath(data)/output/result.txtp.parent.mkdir(parentsTrue,exist_okTrue)p.write_text(hello,encodingutf-8)contentp.read_text(encodingutf-8)本章小结map/filter配合 lambda 做数据变换但列表推导式通常更清晰any/all做批量条件判断sortedkey参数可以自定义排序规则datetime处理日期时间timedelta做时间差计算collections里的deque、Counter、defaultdict很实用functools.lru_cache一行代码就能给函数加缓存面试题Q1map()和列表推导式有什么区别哪个更推荐点击查看答案功能上等价都能对序列中每个元素做变换# maplist(map(lambdax:x**2,[1,2,3]))# 列表推导式[x**2forxin[1,2,3]]区别可读性简单变换用 map 还行复杂的逻辑列表推导式更清晰灵活性列表推导式可以加if过滤map 不行需要配合 filter性能差别很小不需要纠结Python 社区更推荐列表推导式Pythonic除非已有现成函数如map(str, numbers)。Q2lru_cache是怎么工作的什么场景适合用点击查看答案lru_cache用 LRULeast Recently Used算法缓存函数的返回值。参数相同时直接返回缓存结果不重新计算。适合场景递归如 Fibonacci避免重复计算重复查询如配置读取、API 调用纯函数同样的输入总是同样的输出不适合有副作用的函数如写文件、修改全局变量因为第二次调用不会真正执行。maxsize控制缓存大小None表示不限制。Q3datetime中timedelta的用途是什么点击查看答案timedelta表示两个时间点之间的时间差可以做日期时间的加减运算fromdatetimeimportdatetime,timedelta nowdatetime.now()tomorrownowtimedelta(days1)two_hours_laternowtimedelta(hours2)last_weeknow-timedelta(weeks1)# 两个 datetime 相减得到 timedeltadiffdatetime(2024,12,31)-datetime(2024,1,1)print(diff.days)# 365支持 days、seconds、microseconds、milliseconds、minutes、hours、weeks 参数。Q4deque和list有什么区别什么时候用 deque点击查看答案操作listdeque末尾增删O(1)O(1)头部增删O(n)O(1)中间增删O(n)O(n)随机访问O(1)O(n)list 在头部插入/删除是 O(n)所有元素后移deque 是 O(1)。用 deque 的场景需要在两端操作如队列、双端队列需要限制最大长度deque(maxlenN)实现滑动窗口用 list 的场景需要随机访问lst[i]主要在末尾操作