1. 引言
刷题时经常被一些“平时知道,用的时候忘了”的操作卡住,比如index、max、pop、reverse,以及Counter、defaultdict、deque等。更重要的是,力扣习惯了核心代码模式,面对 ACM 模式的输入输出会手忙脚乱。本文统一以def main(): ... if __name__ == "__main__": main()的骨架,整理常用数据类型的方法、collections 高频工具,以及各类输入输出样例,不涉及具体算法,专做基础补全。
2. 常用数据类型与方法速查
这里只列刷题最常用的方法,按可变/不可变、返回值、原地操作分类,避免混淆。
2.1 列表 list
li=[3,1,2]li.append(4)# 末尾追加li.pop()# 弹出末尾,返回元素li.pop(1)# 按下标弹出li.insert(1,5)# 在下标 1 插入 5li.remove(3)# 按值删除第一个匹配项li.index(2)# 返回第一个 2 的下标li.count(2)# 统计 2 的出现次数li.sort()# 原地排序,返回 Noneli.sort(reverse=True)# 降序sorted_li=sorted(li)# 返回新列表,不改变原列表sorted_li=sorted(li,reverse=True)li.reverse()# 原地反转,返回 Nonereversed_li=list(reversed(li))# 返回迭代器,需转列表max(li)# 最大值min(li)# 最小值sum(li)# 求和len(li)# 长度all(li)# 全部为 Trueany(li)# 任一为 True# 列表推导式squares=[x**2forxinrange(10)]2.2 字符串 str
s="hello world"s.split()# ['hello', 'world']s.split('o')# ['hell', ' w', 'rld']s.find('w')# 返回第一个下标,未找到返回 -1s.index('w')# 同上,未找到抛 ValueErrors.count('l')# 统计子串次数s.replace('world','python')# 替换s.startswith('he')# 是否以 he 开头s.endswith('ld')# 是否以 ld 结尾' '.join(['a','b','c'])# 连接列表元素s.strip()# 去除首尾空白s.lstrip()/s.rstrip()s.isdigit()# 是否为全数字s.isalpha()# 是否为全字母s.upper()/s.lower()s[::-1]# 反转字符串2.3 字典 dict
d={'a':1,'b':2}d['a']# 取值(键不存在抛 KeyError)d.get('c',0)# 安全取值,不存在返回 0d.keys()/d.values()/d.items()fork,vind.items():...d.pop('a')# 弹出键并返回值d.popitem()# 弹出最后插入的键值对(3.7+ 有序)d.update({'c':3})# 合并字典deld['b']# 删除键值对2.4 集合 set
s={1,2,3}s.add(4)s.remove(2)# 元素不存在抛 KeyErrors.discard(5)# 安全删除s.pop()# 随机弹出s1&s2# 交集s1|s2# 并集s1-s2# 差集s1^s2# 对称差集2.5 栈、队列与堆
栈直接用list模拟:append + pop。队列推荐collections.deque(见第 3 节)。堆使用heapq:
importheapq heap=[]heapq.heappush(heap,3)heapq.heappush(heap,1)val=heapq.heappop(heap)# 弹出最小值heapq.heapify([3,1,2])# 原地建堆# 大顶堆可以通过存储负数实现3. collections 高频工具
3.1 Counter —— 计数器
fromcollectionsimportCounter cnt=Counter("abracadabra")cnt['a']# 5cnt.most_common(2)# [('a', 5), ('b', 2)]cnt.update("aaaa")# 增加计数cnt.subtract("aa")# 减少计数3.2 defaultdict —— 带默认值的字典
fromcollectionsimportdefaultdict d=defaultdict(int)# 默认值 0d['x']+=1# 不需要判断键是否存在d=defaultdict(list)# 默认空列表d['y'].append(1)d=defaultdict(set)# 默认空集合3.3 deque —— 双端队列
fromcollectionsimportdeque q=deque([1,2,3])q.append(4)# 右侧入队q.appendleft(0)# 左侧入队q.pop()# 右侧出队q.popleft()# 左侧出队q.rotate(1)# 右移 1 位4. ACM 模式输入输出骨架
所有示例统一采用以下模板:
importsysdefmain():passif__name__=="__main__":main()使用sys.stdin.read()/sys.stdin.readline()处理输入,比input()更快,且更适配多行场景。
4.1 单行输入
样例:3 5 7
defmain():line=sys.stdin.readline().strip()nums=list(map(int,line.split()))print(nums)# [3, 5, 7]4.2 多行输入(已知行数)
样例:
3 # 接下来有 3 行 1 2 3 4 5 6 7 8 9defmain():n=int(sys.stdin.readline())matrix=[]for_inrange(n):row=list(map(int,sys.stdin.readline().split()))matrix.append(row)print(matrix)4.3 无限输入(直到 EOF)
样例:
1 2 3 4 5 6 (EOF)defmain():forlineinsys.stdin:a,b=map(int,line.split())# 处理每一行4.4 多组测试用例(首行给出 T)
样例:
2 3 4 5 5defmain():data=sys.stdin.read().strip().split()t=int(data[0])idx=1for_inrange(t):n=int(data[idx]);idx+=1m=int(data[idx]);idx+=1# 处理一组4.5 单行输入一个列表(带空格)
样例:1 2 3 4 5
defmain():arr=list(map(int,sys.stdin.readline().split()))4.6 单行输入一个字符串(可能含空格)
defmain():s=sys.stdin.readline().strip()# 去除末尾换行和空格若要保留行内空格,用.rstrip('\n')。力扣输入通常没有多余空格。
4.7 输入多行字符串列表
样例:
abc def ghidefmain():n=int(sys.stdin.readline())strs=[sys.stdin.readline().strip()for_inrange(n)]或用无限输入:
defmain():strs=[line.strip()forlineinsys.stdin]5. 常见数据结构的输入输出写法
5.1 链表
力扣核心模式给出链表头节点;ACM 模式通常给一个数组,需要自己构建链表并返回头节点。输出也常需打印链表整个序列。
classListNode:def__init__(self,val=0,next=None):self.val=val self.next=nextdefbuild_linked_list(nums):"""从列表构建链表,返回头节点"""dummy=ListNode()cur=dummyfornuminnums:cur.next=ListNode(num)cur=cur.nextreturndummy.nextdefprint_linked_list(head):"""打印链表(假设节点值用 -> 连接)"""res=[]whilehead:res.append(str(head.val))head=head.nextprint("->".join(res))defmain():# 样例输入:1 2 3 4nums=list(map(int,sys.stdin.readline().split()))head=build_linked_list(nums)# 调用解题函数# ...print_linked_list(head)5.2 二叉树
ACM 模式通常给层序遍历序列(null/None表示空节点),需要构建树;输出常为前中后序或层序。
classTreeNode:def__init__(self,val=0,left=None,right=None):self.val=val self.left=left self.right=rightdefbuild_tree(vals):"""vals: 列表,None 表示空节点(层序)"""ifnotvals:returnNoneroot=TreeNode(vals[0])queue=deque([root])i=1whilequeueandi<len(vals):node=queue.popleft()ifi<len(vals)andvals[i]isnotNone:node.left=TreeNode(vals[i])queue.append(node.left)i+=1ifi<len(vals)andvals[i]isnotNone:node.right=TreeNode(vals[i])queue.append(node.right)i+=1returnrootdefmain():line=sys.stdin.readline().strip()# 输入如 "1,2,3,null,4"parts=line.replace("null","None").split(",")vals=[int(x)ifx!="None"elseNoneforxinparts]root=build_tree(vals)# ...5.3 图(邻接表/邻接矩阵)
图常以边列表形式给出,例如第一行n m表示节点数、边数,接下来m行每行u v表示边。
无向图邻接表:
defmain():n,m=map(int,sys.stdin.readline().split())graph=[[]for_inrange(n)]for_inrange(m):u,v=map(int,sys.stdin.readline().split())graph[u].append(v)graph[v].append(u)有向带权图邻接表:
defmain():n,m=map(int,sys.stdin.readline().split())graph=[[]for_inrange(n)]for_inrange(m):u,v,w=map(int,sys.stdin.readline().split())graph[u].append((v,w))6. 更复杂的输入样例
6.1 不定个数的一行列表
直接读一行并按空格分割:
defmain():arr=list(map(int,sys.stdin.readline().split()))6.2 多行不定个数,每行不同格式
defmain():lines=sys.stdin.read().strip().splitlines()forlineinlines:ifnotline:continueparts=line.split()# 根据 parts[0] 判断处理方式6.3 包含字符串和数字混合的行
defmain():tokens=sys.stdin.readline().split()name=tokens[0]age=int(tokens[1])7. 总结
本文整理了 Python 刷题中容易被遗忘的常用方法,以及从简单到复杂的 ACM 输入输出写法,全部以def main() + if __name__ == "__main__": main()统一呈现。建议将此文加入收藏,碰到陌生输入或遗忘方法时快速查阅。后续如需补充其他数据结构或技巧,可随时扩充。