Python 语法 **python代码有严格的缩进限制,不同的缩进代表了不同的含义,请不要随意缩进!!!**
变量类型 python**不需要** 预先声明变量,并且没有显式的类型声明,python 代码最后**不需要加分号**
1 2 3 4 5 a = b = c = 1 d,e,f = 777 , 3.14159 , "eeee"
数字
数字类型的变量理论上可以存储无限大的数,但是会受限于计算机的运算速度。
str(字符串类型)
不论双引号"ABC",还是单引号 ‘ABC’ ,代表的都是字符串(即使是'a' ,也是长度为一的字符串,而不是字符)
列表(list)
列表使用**中括号**表示。
类似于C中的数组,能够存储一些数据,支持按下标找值。列表中可以存放任何类型,并且**单个列表可以存放多种类型**
1 2 3 4 5 6 7 8 a = [0 ,[1 ,2 ,2 ,5 ],[[1 ]] ]
元组(tuple)
元组用小括号()表示
和列表类似,常用来函数返回多个值
1 2 3 4 5 6 7 8 9 tup = (111 ,222 ,"abc" ) print (type (tup))print (tup[1 ]) def func (): name = 'ttt' age = 114 score = 514 return name,age,score print (func())
元组同样可以使用下标来访问
集合(set)
集合中的元素无序,不重复。
1 2 a = {-1 ,3 ,-5 ,3 ,2 ,4 ,4 ,4 } print (a)
字典(dict)
字典,顾名思义,就是用来查找值的,每一项是一个**键值对**,我们通过键可以找到对应的值,每个键值对表示为 **key : value** .即一个冒号,左边是键,右边是值。
1 dic = {"mike" : 1000 , "Lisa" : 111 , 114 : 514 }
其中”mike”, “Lisa”,114是键, 1000,111,514 是对应的值。
假设dic是一个字典,使用dic.pop(“mike”) 来清除mike这个键值对。 使用dic[“aaa”] = “ttt” 来加入一个键值对。
如果我们要判断一个键值对是否存在,应该使用
1 2 3 4 5 6 7 dic = {"mike" : 1000 , "Lisa" : 111 , 114 : 514 } dic[222 ] = 456 print (dic[222 ])print (dic.get(222 ))dic.pop(114 ) if (not dic.get(114 )): print ("No!" )
输入输出 输入使用input() 函数,input函数有以下几个特性:
会直接读取完一整行
读入后的数据以字符串的形式表示
1 2 3 4 5 6 a = input () print (type (a))
我们经常需要使用**强制类型转换来**变成其他形式的值
如果一行有多个整数需要输入怎么办???
1 2 3 4 5 6 7 8 9 10 lst = input () lst = input ().split() lst = map (int ,input ().split()) lst = list (map (int ,input ().split()))
输出 格式化输出:
在字符串前加f,然后字符串内加大括号,{}
1 2 3 a = 55 b = "bbb" print (f"a is {a} , b is {b} " )
确定小数位数用:
1 2 a = 55.00 print ("{:.5f}" .format (a))
不想让print之后换行
1 2 3 print ("abc" ,end=" " )print ("bcd" ,end="" )
判断 判断和C中的判断基本一样,区别在于 C中的else if 要换成**elif**
1 2 3 4 5 6 7 8 9 int a = 77 ;if (a < 60 ){ printf ("Bad!\n" ); }else if (a < 80 ){ printf ("Good!\n" ); }else { printf ("Perfect!" ); }
1 2 3 4 5 6 7 8 9 a = 77 if a < 60 : print ("Bad" ) elif (a < 80 ): print ("Good!" ) else : print ("Perfect!" )
循环 循环一般使用for和while循环:
for循环 for循环用来遍历某个可枚举的类型(集合,列表,元组,字典,range等等)
先来看看range
1 2 3 4 5 6 7 8 9 range (5 ) range (5 ,12 ) range (3 ,8 ,1 ) range (3 ,8 ,2 ) range (9 ,3 ,-2 )
因此我们的for循环应该这么用:1 2 3 4 5 for i in range (8 ): print (i) lst = [5 ,7 ,"bcc" ,123 ,677.001 ] for i in lst: print (i)
while循环 while循环和C中的用法一样,不再赘述
特殊性质 Python中的循环可以加**else**,表示循环正常结束时进行的操作:(如果使用break中断循环就不会进行else中的操作)
1 2 3 4 for i in range (5 ): print (i) else : print (777 )
运算 和C相同的运算就不说了,下面说一下不同:
整数除法//
求次方 **
合并数据类型 + *
1 2 3 4 5 6 7 8 9 str1,str2 = "AB" ,"CD" print (str1+str2)print (str1 * 3 ) lst1 = [1 ,2 ,3 ] lst2 = [3 ,4 ,5 ] print (lst1+lst2)print (lst1*3 )
一些小技巧(注意点) 快读
使用input输入数据比较慢,有时候可能会导致超时,需要换成sys.stdin.readline()
1 2 import sys num = int (sys.stdin.readline())
[B2056 求整数的和与均值 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)](https://www.luogu.com.cn/problem/B2056 )
使用input耗时85ms
1 2 3 4 5 6 n = int (input ()) sum = 0 for i in range (n): num = int (input ()) sum += num print ('{} {:.5f}' .format (sum ,sum /n))
使用readline耗时58ms
1 2 3 4 5 6 7 import sysn = int (sys.stdin.readline()) sum = 0 for i in range (n): num = int (sys.stdin.readline()) sum += num print ('{} {:.5f}' .format (sum ,sum /n))
注意避免浅拷贝 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 a1 = [1 ,2 ,3 ,4 ,5 ] b1 = a1 a1[0 ] = 114514 print (b1) a2 = [1 ,2 ,3 ,4 ,5 ] b2 = a2[:] c2 = a2.copy() a2[0 ] = 114514 print (b2) print (c2) a3 = [[1 ,2 ],[3 ,4 ]] b3 = a3[:] c3 = a3.copy() a3[0 ][0 ] = 114514 print (b3) print (c3) a4 = [[1 ,2 ],[3 ,4 ]] b4 = [] for i in range (len (a4)): tmp = [] for j in range (len (a4[i])): tmp.append(a4[i][j]) b4.append(tmp) a4[0 ][0 ] = 114514 print (b4)
二维数组的定义: 错误样例:
此时当我们使用, 修改第6行第3列这个元素时,会导致整个第3列都变成这个值(我也搞不懂为什么)
正确示范:
append函数用来向列表的末尾插入一个元素
1 2 3 arr = [] for i in range (50 ): arr.append([0 ] * 100 )
快速幂 python的pow函数内置了快速幂
[P1226 【模板】快速幂 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)](https://www.luogu.com.cn/problem/P1226 )
C代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <stdio.h> #define int long long int quickpow (int x,int n,int p) { int ans = 1 ; while (n){ if (n & 1 ) ans = ans * x % p; x = x * x % p; n >>= 1 ; } return ans; } signed main () { int a,b,p; scanf ("%lld %lld %lld" ,&a,&b,&p); printf ("%lld^%lld mod %lld=%lld" ,a,b,p,quickpow(a,b,p)); }
python代码如下:
1 2 a,b,p = list (map (int ,input ().split())) print (f"{a} ^{b} mod {p} ={pow (a,b,p)} " )
高精度 python内置了高精度运算
[P1601 A+B Problem(高精) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)](https://www.luogu.com.cn/problem/P1601 )
1 2 a,b = int (input ()),int (input ()) print (a+b)
[P1480 A/B Problem - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)](https://www.luogu.com.cn/problem/P1480 )
1 2 a,b = int (input ()),int (input ()) print (a//b)
自测代码用时 python蓝桥杯中一般会给10s的时间,但我们如何知道我们的代码大概用了多少时间?
1 2 3 4 5 6 7 8 import timetic = time.time() a = 0 for i in range (int (1e8 )): a += i tok = time.time() print (tok-tic)
我们在代码的最上面和最下面分别记录当前的时间,然后输出二者的差。
在我自己的电脑cpu:R6800H上运行了8.4s, 而一般测评机只会更差,于是我们可以大致估算出python一秒能够支持大概 次算术运算。
datetime 可能不会再出日历题了,但是还是放在这边叭。
1 2 3 4 5 6 7 8 9 10 from datetime import datetimedate_time_1 = datetime(2025 ,3 ,29 ,12 ,5 ,13 ) date_time_2 = datetime(2026 ,6 ,1 ,17 ,5 ,20 ) delta = date_time_2 - date_time_1 print (delta.days) print (delta.seconds) print (delta.total_seconds())
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 from datetime import datedate1 = date(2020 , 2 , 28 ) date2 = date(2020 , 3 , 1 ) delta = date2 - date1 print (delta.days) def cal_sunday (y,m,d ): dat1 = date(1900 ,1 ,1 ) dat2 = date(y,m,d) sunday_cnt = 0 while (dat1 < dat2): if (dat1.weekday() == 6 ): sunday_cnt += 1 dat1 += date.resolution print (sunday_cnt) cal_sunday(2025 ,4 ,8 )
自定义排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Node : def __init__ (self, x, y ): self .x = x self .y = y def __lt__ (self, other ): if self .x == other.x: return self .y < other.y return self .x < other.x def __repr__ (self ): return f"Node(x={self.x} , y={self.y} )" nodes = [ Node(1 , 2 ), Node(1 , 1 ), Node(2 , 3 ), Node(2 , 1 ), Node(3 , 4 ) ] nodes.sort() from queue import PriorityQueuepq = PriorityQueue() pq.put(Node(1 , 5 )) pq.put(Node(1 , 1 )) pq.put(Node(4 , 4 )) while (not pq.empty()): print (pq.get())
数据结构 C++转python 此处通过一些“等价”的代码来介绍一些C++和python共同的数据结构。
vectorundefinedto$ list 1 2 3 4 5 6 vector<int > vec (114 ,514 ) ;vec.push_back (1919810 ); cout<<vec.back ()<<endl; vec.clear (); cout<< vec.size ()<<endl;
1 2 3 4 5 6 a = [514 ] * 114 a.append(1919810 ) print (a[-1 ])a.clear() print (len (a))
map undefinedto$ dict 注意:
python中的dict在遍历时并不会保持有序
python中的dict使用dic[key]访问值,在遇到不存在的key会直接报错。
collections库中包含一个OrderedDict,但这里的ordered指代的”有序“并非像C++那样键的有序。而是保持插入顺序,因此在算法竞赛中通常用不到OrderedDict。
1 2 3 4 5 6 7 8 9 10 11 map<int ,int > mp; mp[114 ] = 514 ; cout<<mp[2 ]<<endl; mp.erase (2 ); mp.clear (); for (pair<int ,int > pii : mp){ int x = pii.first; int y = pii.second; cout<<x<<" " <<y<<endl; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 dic = dict () dic[114 ] = 514 print (dic.get(2 ,0 )) if (dic.get(2 ,None ) == None ): dic[2 ] = 0 print ("dic[2] is not exist" ) dic.pop(2 ) dic.clear() dic[6 ] = 1 dic[5 ] = 2 dic[4 ] = 3 for x,y in dic.items(): print (x,y)
也可以使用collections中的defaultDict,这个数据结构支持为字典定义默认值,从而避免访问不存在的key而报错。
1 2 3 4 default_dic = defaultdict(lambda :-1 ) print (default_dic['a' ]) dic = dict () print (dic['a' ])
set undefinedto$ set 注意python中的set是无序的。可以使用sorted来将set变为有序的list。
1 2 3 4 5 6 7 8 9 set<int > st = {1 ,1 ,4 ,5 ,1 ,4 }; st.insert (5 ); st.erase (5 ); cout << st.count (5 )<<endl; cout << *st.begin ()<<endl; for (int x : st){ cout << x << ' ' ; }
1 2 3 4 5 6 7 8 st = set ([1 ,1 ,4 ,5 ,1 ,4 ]) st.add(5 ) st.remove(5 ) print (5 in st) for x in st: print (x,end = ' ' )
queue undefinedto$ Queue 注意python中的获取队首元素 get方法,会将队首弹出。
而C++中获取首元素que.front()并不会弹出该元素。
虽然queue理论上只能访问队首元素,但是在python的Queue中我们可以直接遍历查看queue的每一个元素的值。
注意Queue的大小写
1 2 3 4 5 6 7 queue<int > que; que.push (1 );que.push (1 );que.push (4 ); que.push (5 );que.push (1 );que.push (4 ); cout<< que.front ()<<' ' << que.back ()<<endl; que.pop (); cout << que.size ();
1 2 3 4 5 6 7 8 9 10 11 12 13 from queue import Queueque = Queue() que.put(1 );que.put(1 );que.put(4 ) que.put(5 );que.put(1 );que.put(4 ) print (que.queue[0 ],que.queue[-1 ]) que.get() print (que.qsize()) for x in que.queue: print (x,end=' ' )
priority_queue undefinedto$ PriorityQueue
注意python中的Priority Queue默认是小根堆(我们可以通过定义一个类,然后重写它的__lt__ 方法,来实现其他排序方式的堆,详见本文之前的“自定义排序”小节。)
注意PriorityQueue的大小写
1 2 3 4 5 6 priority_queue<int > pq; pq.push (1 ); pq.push (1 ); pq.push (4 ); pq.push (5 ); pq.push (1 ); pq.push (4 ); pq.pop (); cout<< pq.top ();
1 2 3 4 5 6 7 from queue import PriorityQueuepq = PriorityQueue() pq.put(1 );pq.put(1 );pq.put(4 ) pq.put(5 );pq.put(1 );pq.put(4 ) pq.queue[0 ] top = pq.get()
deque undefinedto$ deque 和queue类似,虽然deque只能从两端进出元素,但我们仍然可以直接枚举整个队列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 deque<int > dq; dq.push_back (1 );dq.push_back (2 );dq.push_back (3 ); dq.push_front (0 ); int right_element = dq.back (); dq.pop_back (); cout << right_element << endl; int left_element = dq.front (); dq.pop_front (); cout << left_element << endl; for (const auto & x : dq) { cout << x << " " ; }cout << endl; int front_element = dq.front ();cout << front_element << endl; int back_element = dq.back ();cout << back_element << endl; int queue_size = dq.size ();cout << queue_size << endl; dq.insert (dq.end (), {3 , 4 , 5 }); for (const auto & x : dq) { cout << x << " " ; }cout << endl; dq.insert (dq.begin (), {0 , -1 }); for (const auto & x : dq) { cout << x << " " ; }cout << endl; for (const auto & x : dq) { cout << x << " " ; }cout << endl;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 from collections import dequedq = deque() dq.append(1 ) ;dq.append(2 );dq.append(3 ) dq.appendleft(0 ) right_element = dq.pop() print (right_element) left_element = dq.popleft() print (left_element) print (dq) front_element = dq[0 ] print (front_element) back_element = dq[-1 ] print (back_element) queue_size = len (dq) print (queue_size) dq.extend([3 , 4 , 5 ]) print (dq) dq.extendleft([0 , -1 ]) print (dq) for x in dq: print (x,end = " " )
stack undefinedto$ list 推荐用list来模拟,(类似于C++中的用vector模拟栈)。list的用法详见vector undefinedto$ list 篇