1.常用操作
.以空格为分隔接入数据
m , n = map(int,input().split())
desk = [list(map(int,input().split())) for i in range(N)]
toy = [int(input()) for i in range (M)]
#注意 map返回的是一个map对象 使用列表生成式时需要加上list()
.以空格为间隔输出数据
print(desk[j][i],end=' ')
print(*res,end=' ')
.字符串格式化
print('The ans is {0:.8f}'.format(Fib(N)/Fib(N+1)))
print("%.8f"%(F(number)/F(number+1)))
.复制列表(浅复制)
b = a[:]
b = list(a)
.比较大小(二维数组)
score.sort(key=lambda s:(s[3],s[0]),reverse=True)
.比较字符
s = 'LANQIAO'
lis = [ord(x) for x in s]
sum1 = 0
for i in lis:
for j in lis:
sum1 += abs(i-j)
print(sum1 // 2)
#这里就是把一个个字符转化为ascil码,并计算距离 abs为计算绝对值
.初始化数组
desk = [[0 for y in range(4)] for x in range(4)]
desk1 = [[float('inf') for y in range(4)] for x in range(4)]
desk2 = [[float('-inf') for y in range(4)] for x in range(4)]
.取整问题
1、向上取整
import math
>>> math.ceil(4.12)
5
2、向下取整
import math
>>> math.floor(4.12)
4
3、四舍五入
>>> round(2.3)
2
>>> round(2.6)
3
.生成a-z字符
list1 = [chr(i).upper() for i in range(97,123)]
dicts = {chr(x) : 0 for x in range(97,123)}
.日期类
import datetime
start = datetime.date(2020,1,1)
end = datetime.date(2020,10,1)
days = datetime.timedelta(days=1)
对于datetime.date类的操作
datetime.date.weekday():返回日期的星期 n-1
datetime.date.isoformat():返回格式如YYYY-MM-DD
datetime.date.strftime(format):把日期时间按照给定的format进行格式化。
datetime.timedelta(days,days=0, seconds=0, microseconds=0,
milliseconds=0, minutes=0, hours=0, weeks=0)
用来计算两个datetime.datetime或者datetime.date类型之间的时间差。
python中时间日期格式化符号:
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
.初始化字典
使用collection的defaultdict可以简单的初始化字典
from collections import defaultdict
dd = defaultdict(list)
defaultdict(<type 'list'>, {})
#给它赋值,同时也是读取
dd['h'h]
defaultdict(<type 'list'>, {'hh': []})
dd['hh'].append('haha')
defaultdict(<type 'list'>, {'hh': ['haha']})
2.序列基本操作
.字典
dict.get(key,item) 找到key对应的value,没有则返回item
统计每个字符个数
for i in strr:
d[i] = d.get(i,0) + 1
解包打印
for key,value in money_dict.items():
print(key,value,sep=':')
>>>
100:3
50:1
20:0
5:3
1:0
.列表
list.index()返回该值在列表的索引
坑: 注意,在一个循环删除列表元素时,要采用倒序删除
.字符串
删除指定字符
string.replace('str','')
3.常用算法
求两数的最大公约数 gcd(辗转相除法)
def gcd(a,b):
if b == 0:
return a
else:
return gcd(b,a%b)
或直接用库
import math #导入math库
print(math.gcd(a,b)) #利用函数求解最大公约数
print(a*b/math.gcd(a,b)) #利用上面的函数求解最小公倍数
判断质数
def is_prime(x):
if x == 2:
return True
elif x % 2 == 0:
return False
for i in range(3, int(x ** 0.5) + 1, 2):
if x % i == 0:
return False
return True
排列组合(从n个不重复的元素中选出r个) Cmn(不考虑顺序)
def combinations(source: list, n: int) -> list:
'''从一个元素不重复的列表里选出n个元素
:参数 source:元素不重复的列表
:参数 n: 要选出的元素数量,正整数,小于等于列表source的长度
'''
# 如果n正好等于列表的长度,那么只有一种组合
# 就是把所有元素都选出来
if len(source) == n:
return [source]
# 如果n是1,那么列表中的每个元素都是一个组合
if n == 1:
ans = []
for i in source:
ans.append([i])
return ans
# 下面处理n小于列表长度的情况
ans = []
# 从列表里选n个元素出来,可以理解为先把列表里的第0个元素拿出来放进组合
# 然后从剩下的元素里选出n-1个
for each_list in combinations(source[1:], n - 1):
ans.append([source[0]] + each_list)
# 还可以直接从剩下的元素里选出n个
for each_list in combinations(source[1:], n):
ans.append(each_list)
return ans
# 当然,也可以用python的内置模块itertools
import itertools
a = [1,2,3,4,5]
totallist = []
for i in itertools.combinations(a,3):
totallist.append(list(i))
print(totallist)
>>> [[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2, 3, 5], [2, 4, 5], [3, 4, 5]]
若要选择带上重复了元素 可以用combinations_with_replacement()
>>> [[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 1, 4], [1, 1, 5], [1, 2, 2], [1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 3], [1, 3, 4], [1, 3, 5], [1, 4, 4], [1, 4, 5], [1, 5, 5], [2, 2, 2], [2, 2, 3], [2, 2, 4], [2, 2, 5], [2, 3, 3], [2, 3, 4], [2, 3, 5], [2, 4, 4], [2, 4, 5], [2, 5, 5], [3, 3, 3], [3, 3, 4], [3, 3, 5], [3, 4, 4], [3, 4, 5], [3, 5, 5], [4, 4, 4], [4, 4, 5], [4, 5, 5], [5, 5, 5]]
A全排列(考虑顺序)
# 递归
res = []
def calc(li,begin,end):
global res
if begin >= end:
temp = li[:]
res.append(temp)
else:
for i in range(begin,end):
li[i],li[begin] = li[begin],li[i]
calc(li,begin+1,end)
li[i], li[begin] = li[begin], li[i]
return res
arr = [1,2,3]
print(calc(arr,0,len(arr)))
#深度优先搜索
visit = [True, True, True, True]
temp = ["" for x in range(0, 4)]
def dfs(position):
global arr
# 递归出口
if position == len(arr):
print(temp)
return
# 递归主体
for index in range(0, len(arr)):
if visit[index] == True:
temp[position] = arr[index]
visit[index] = False # 试探
dfs(position + 1)
visit[index] = True # 回溯。非常重要
arr = [1, 2, 3, 4]
dfs(0)
#同样,可以继续使用itertools模块的permutations 返回p中任意取r个元素做排列的元组的迭代器
import itertools
a = [1,2,3,4,5]
totallist = []
for i in itertools.permutations(a,5):
totallist.append(list(i))
print(totallist)
二分查找
#在单调递增序列a中查找>=x的数中最小的一个(即x或x的后继)
while low<high:
mid=(low+high)/2
if(a[mid]>=x):
high=mid
else:
low=mid+1
#在单调递增序列a中查找<=x的数中最大的一个(即x或x的前驱)
while low<high:
mid=(low+high+1)/2
if(a[mid]<=x):
low=mid
else:
high = mid-1
也可以用bisect模块
bisect.bisect_left(a, x, lo=0, hi=len(a)):a是列表,x是要插入的元素。函数返回在a中插入x的位置,如果a中已经存x,那么插入的位置在a中最左边的x的前面一位。返回值把列表分成两部分,插入点左侧满足all(val < x for val in a[lo:i]),插入点右侧满足all(val >= x for val in a[i:hi])。
bisect.bisect_right(a, x, lo=0, hi=len(a)):与bisect.bisect_left的不同点在于,如果a中已经存x,那么插入的位置在a中最右边的x的后面一位。
bisect.bisect(a, x, lo=0, hi=len(a)):与bisect.bisect_right相同。返回值把列表分成两部分,插入点左侧满足all(val <= x for val in a[lo:i+1]),插入点右侧满足all(val > x for val in a[i+1:hi])。
bisect.insort_left(a, x, lo=0, hi=len(a)):返回插入元素后的列表。先使用bisect.bisect_left获得插入元素的位置,然后在该位置插入元素并返回列表。等价于a.insert(bisect.bisect_left(a, x, lo, hi), x)。
bisect.insort_right(a, x, lo=0, hi=len(a)):等价于a.insert(bisect.bisect_right(a, x, lo, hi), x)。
bisect.insort(a, x, lo=0, hi=len(a)):等价于a.insert(bisect.bisect(a, x, lo, hi), x)。
最小生成树
def prim():
global cost,used,mincost,n
ans = 0
mincost[0] = 0
while True:
v = -1
for i in range(n):
if (used[i] == False) and (v == -1 or mincost[i] < mincost[v]): #这一步实际上是从mincost里找与上一个顶点之间权值最小的顶点
v = i
if v == -1:
break
used[v] = True
ans += mincost[v]
for i in range(n):
mincost[i] = min(mincost[i],cost[v][i])
return ans
笛卡尔积
使用itertools的product()
product(iter1,iter2, ... iterN, [repeat=1]);创建一个迭代器,生成表示item1,item2等中的项目的笛卡尔积的元组,repeat是一个关键字参数,指定重复生成序列的次数
# itertools.product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
# itertools.product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
最短路径
#最短路径问题
##Floyd算法
def Floyd(n):
global dis
for k in range(n): #中转点
for v in range(n): #起点
for w in range(n): #终点
dis[v][w] = min(dis[v][w] , dis[v][k] + dis[k][v])
#Dijkstra
N, M = map(int, input().split())
cost = [[float('inf') for j in range(N)] for i in range(N)]
for i in range(M):
s, e, v = map(int, input().split())
cost[s - 1][e - 1] = cost[e - 1][s - 1] = v
flag = [False for i in range(N)]
d = [float('inf') for i in range(N)]
d[0] = 0
while True:
u = -1
for i in range(N):
if (flag[i] == False) and (u == -1 or d[u] > d[i]):
u = i
if u == -1:
break
flag[u] = True
for i in range(N):
d[i] = min(d[i], d[u] + cost[u][i])
4.基本数据结构
#并查集
class UnionFindSet():
def __init__(self, data_list):
"""初始化两个字典,一个保存节点的父节点,另外一个保存父节点的大小
初始化的时候,将节点的父节点设为自身,size设为1"""
self.father_dict = {}
self.size_dict = {}
for node in data_list:
self.father_dict[node] = node
self.size_dict[node] = 1
def find(self,node):
father = self.father_dict[node]
if (node != father):
if father != self.father_dict[father]:
self.size_dict[father] -= 1
father = self.find(father)
self.father_dict[node] = father
return father
def is_same_set(self, node_a, node_b):
"""查看两个节点是不是在一个集合里面"""
return self.find(node_a) == self.find(node_b)
def union(self, node_a , node_b):
"""将两个集合合并在一起"""
if node_a is None or node_b is None:
return
a_head = self.find(node_a)
b_head = self.find(node_b)
if (a_head != b_head):
a_set_size = self.size_dict[a_head]
b_set_size = self.size_dict[b_head]
if (a_set_size >= b_set_size):
self.father_dict[b_head] = a_head
self.size_dict[a_head] = a_set_size + b_set_size
else:
self.father_dict[a_head] = b_head
self.size_dict[b_head] = a_set_size + b_set_size
优先队列
from queue import PriorityQueue
cost = PriorityQueue()