前面讲到collections模块中基于字典的扩展,collections是Python的内置标准库模块,提供专门的容器数据类型,用于替代通用容器dict,list,set,tuple,在他们的基础上增加了新功能。那么常用的collections模块:defaultdict,Counterdefaultdict:彻底解决了分组,统计时频繁判断键是否存在的痛点,可用于按某个字段分组数据,统计频次,构建复杂的嵌套结构from collections import defaultdictgroups = defaultdict(list)for word in words: groups[word].append(word) #直接append,键不存在时自动创建空列表print(groups)dd = defaultdict(int) #int()返回0dd['a']+=1 #正常运行print(dd) #{'a':1}defaultdict(list) #默认[],用于分组defaultdict(set) #默认set(),用于去重defaultdict(str) #默认'' 使用时dd['missingg'] += 'x'会变成'x',但实际很少用,因为空字符串在统计场景下不如int或list实用defaultdict(dict) #默认{}#应用from collections import defaultdictwords = ['apple','banana','asen','cat','car']groups = defaultdict(list)for word in words: groups[word[0]].append(word)print(groups) #{'a':['apple','asen'],'b':['banana'],'c':['cat','car']}
Counter:一行代码完成统计,比手动用defaultdict(int)更方便,可用于统计序列中元素出现的次数,找出出现最多的N个元素,多重集合运算(交集,并集)from collections import Counterwords = ['apple','bat','apple','cat','bat','apple']word_counts = Counter(words)print(word_counts.most_common()) #[('apple',3),('bat',2),('cat',1)]text = "hello python hello world"word_count = Counter(text.split())print(word_count.most_common(2)) #[('hello',2),('python',1)] most_common(n):返回出现频率最高的前n个元素,以[(元素,出现次数)]组成的元组列表形式输出
字符串具有不可变性,一个字符串被创建后,就无法修改它内部的字符.lower() #将所有字符转换成小写.upper() #将所有字符转换为大写.capitalize() #将首个字母大写,其余小写.title() #将每个单词的首字母大写
.find(sub) #查找子串sub第一次出现的索引,找不到返回-1,"hello".find("lo")返回3.index(sub) #与find()类似,但找不到会抛出ValueError异常.replace(a,b) #将所有a子串替换为b.count(sub) #计算子串出现的次数.startswith(prefix) #检查字符串是否以prefix开头.endswith(suffix) #检查字符串是否以suffix结尾.isdigit() #检查字符串是否只由数字组成.isalpha() #检查字符串是否只由字母组成.isalnum() #检查字符串是否由字母和数字组成
.strip() #去除字符串两端的空白字符(包括空格,换行\n,制表符\t).lstrip() #去除字符串左侧的空白字符.rstrip() #去除字符串右侧的空白字符.center(width) #将字符串居中,并用空格填充至长度width
.split(sep) #以sep为分隔符,将字符串分割为一个列表 split()如果不传参数,会按任意空白字符(空格,换行,制表符)分割,且自动忽略首尾空白,比split('')更常用.join(iterable) #以当前字符串为分隔符,将一个可迭代对象中的字符串合并成一个新字符串
+:字符串连接 *:字符串重复 in:成员关系判断,检查一个字符串是否包含在另一个字符串中 not in:与in相反 len():获取字符串的长度\n:换行符 \t:水平制表符 \r:回车符 \b:退格符
def greet(name): """"向指定的人问好""" #文档字符串 return f"hello,{name}" #函数体#调用函数result = greet("Alice")print(result) #hello,Alice
1.必须以字母或下划线开头 2.只能包含字母,数字和下划线 3.区分大小写 4.不能使用 python关键字def add(x,y): return x + yresult = add(3,5) #x=3,x=5
def introduce(name,age,city): print(f"{name} is {age} years old,from {city}")introduce(age=25,name="Bob",city="Beijing")
注意:所有位置参数必须出现在默认参数前,包括函数定义和调用。默认参数不要用可变对象(可变对象与不可变对象前期已经提起)def good_append(item,lst=None): #不能写 lst=[] if lst is None: lst = [] lst.append(item) return lst
#*args:接收任意数量的位置参数,打包成元组def sum_all(*args): total = 0 for num in args: total += num return totalprint(sum_all(1,2,3,4,5))#**kwargs:接收任意数量的关键字参数,打包成字典def print_info(**kwargs): for key,value in kwargs.items(): print(f"{key}:{value}")print_info(name="Alice",age=30,city="Shanghai")
位置参数→默认参数→*args→仅关键字参数→**kwargs其中“/”前的参数只能用位置传递,“*”后的参数只能用关键字传递1.单个返回值 2.多个返回值 3.没有返回值(没有return语句)def apply(func,x,y): return func(x,y)def add(a,b): return a+bprint(apply(add,5,3))
#map:对每个元素做 “映射” 转换,用于批量处理,数据转换#filter:按条件筛选符合要求的元素,用于数据过滤,条件筛选#reduce:对所有元素做累积计算,归约为一个值,用于求和,求积,累积统计,注意:Python中已经移到functools模块,需要from functools import reducenumbers = [1,2,3,4]squared = list(map(lambda x: x**2,numbers))print(squared)from functools import reduceproduct = reduce(lambda x,y: x*y,numbers)print(product)
pairs = [(1,"one"),(2,"two"),(3,"three")]pairs.sort(key=lambda pair: pair[1]) #按元组的第二个元素(字符串)排序,不是按数字print(pairs) #[(1,"one"),(3,"three"),(2,"two")] #字符串排序默认按字母顺序(字典序):one→three→two,当首字母相同时,会比较第二个字母
1.不修改原函数或程序的代码 2.不修改函数或程序的调用方法def timer(func): import time def wrapper(*args,**kwargs): start = time.time() #记录开始时间 result = func(*args,**kwargs) #执行被装饰的函数 end = time.time() #记录结束时间 print(f"{func.__name__} took {end-start} seconds") return result return wrapper@timer #等价于执行了slow_function = timer(slow_function)def slow_function(): import time time.sleep(2) return "Done"slow_function()
def fibonacci(n): if n <= 1: return n return fibonacci(n-1) + fibonacci(n-2)
func.custom_attr = "Hello"print(func.custom_attr) #Hello#内置属性print(func.__name__) #函数名print(func.__defaults__) #默认参数print(func.__code__) #代码对象print(func.__dict__) #属性字典
是Python中一种特殊函数,使用yield关键字代替return来返回值,它返回一个生成器对象,可以按需生成值,而不是一次性返回所有结果def countdown(n): """生成器函数""" while n > 0: yield n n -= 1#使用生成器for num in countdown(5): print(num) #5,4,3,2,1
int("123") #转为整型float("3.14") #转为浮点型str(123) #转为字符串类型list((1,2,3)) #元组转列表tuple([1,2,3]) #列表转元组dict([("a",1),("b",2)]) #键值对列表转字典
abs(-5) #绝对值max(1,5,3) #最大值min(1,5,3) #最小值sum([1,2,3]) #求和round(3.14159,2) #四舍五入到指定小数位数
len([1,2,3]) #获取长度range(5) #生成数字序列enumerate(["a","b","c"]) #同时获取索引和值zip([1,2],["a","b"]) #打包成元组,解压用zip(*...)
all([True,True,True]) #True,判断是否所有元素都为Trueany([False,True,False]) #True,判断是否存在至少另一个元素为Trueisistance(5,int) #True,判断是否是某个类的实例
#不好的做法def create_user(name,age,email,city,country,phone,job,salary): pass#好的做法class UserData: def __init__(self,name,age,email,city=None,country=None,phone=None,job=None,salary=None): self.name = name self.age = age #...def create_user(user_data): pass
将相关的参数封装到一个数据类(UserData)中,将多个参数对象打包成一个对象
完整的异常处理结构:try-except-else-finallytry: #可能引发异常的代码 num = int(input("请输入数字:"))except ValueError: #发生异常时执行 print("输入的不是有效数字")else: #没有异常执行 print(f"输入的数字是:{num}")finally: #无论是否异常都执行 print("程序执行完毕")
try: #可能引发异常的代码 passexcept ExceptionType: #处理特定异常的代码 pass
try: passexcept ValueError: passexcept ZeroDivisionError: pass
try: passexcept(ValueError,TypeError) as e: pass
try: result = 10/0except ZeroDivisionError as e: print(f"错误信息:{e}") print(f"错误类型:{type(e)}")
#引发内置异常raise ValueError("参数错误")#根据条件引发异常def divide(a,b): if b == 0: raise ZeroDivisionError("除数不能为0") return a/b#重新引发异常try: divide(10,0)except ZeroDivisionError: print("记录日志...") raise #继续向上抛出
try: int("abc")except ValueError as e: raise RuntimeError("转换失败") from e