Python入门阶段发现的一些小技巧
Python入门阶段发现的一些小技巧
- 对于需要循环遍历,仅仅只需要次数而不需要下标或者具体的值情况下:
for _ in range(10)
- 避免循环和内存的方法就是最好输入后就解决,不要再次调用与保存
其实这些都没必要学习,无论用什么方法,先能写出来才是王道,效率都差不太多,我还没有到那个境界。。。。。 - 巧妙的输入
t = int(stdin.readline())
for n in[*map(int,open(0))][1:]:
if n%2:
m=n//2
d=m%2+1
r=m-d,m+d,1
else:r=2,n-3,1
print(*r)
对于构造的题目(constructive)如果是判断归谬的需要多想想正反两面的问题,因为一开始的想法总是不全面的
最大公约数为1的问题
- 偶数与奇数之间最大公约数为1
- 相邻两个数之间最大公约数为1
- 相邻的奇数最大公约数为1
[comment]: math库里有求最大公约数的函数:
from math import gcd as bltin_gcd
def p(a,b):
return bltin_gcd(a,b)==1#由于是寻找一定会有GCD为1的两个数的,因为没有限制n的大小
- python中整除以及舍入
2//3=0
-1//2=-1#整除时会向小值舍入
round(-2.8)=-3#四舍五入同样的进位操作
-
经过对比可知python自带的input输入没有
sys.stdin.readline().strip()要快,差距大致有100多毫秒,可以使用这种方法来替代:import sys def input(): return sys.stdin.readline().strip()
-
python中判断一个数是否是整数
def judge(num): if num==round(num): return True return False#应该还用别的方法需要对比测试一套最快的算法 -
来自一个菜鸡的叙述,不要怕超时或者算法很SB,没思路就跳走,你当前的能力不足以征服此题,哎用python刷codeforce又又又超时了 😭
-
python中的切片操作!!!!![详解][ https://zhuanlan.zhihu.com/p/79541418#:~:text=什么是切片操作 在Python中, 切片 (slice) 是对序列型对象 (如 list%2C ,string%2C%20tuple%29%E7%9A%84%E4%B8%80%E7%A7%8D%E9%AB%98%E7%BA%A7%E7%B4%A2%E5%BC%95%E6%96%B9%E6%B3%95%E3%80%82%20%E6%99%AE%E9%80%9A%E7%B4%A2%E5%BC%95%E5%8F%AA%E5%8F%96%E5%87%BA%E5%BA%8F%E5%88%97%E4%B8%AD%20%E4%B8%80%E4%B8%AA%E4%B8%8B%E6%A0%87%20%E5%AF%B9%E5%BA%94%E7%9A%84%E5%85%83%E7%B4%A0%EF%BC%8C%E8%80%8C%E5%88%87%E7%89%87%E5%8F%96%E5%87%BA%E5%BA%8F%E5%88%97%E4%B8%AD%20%E4%B8%80%E4%B8%AA%E8%8C%83%E5%9B%B4%20%E5%AF%B9%E5%BA%94%E7%9A%84%E5%85%83%E7%B4%A0%EF%BC%8C%E8%BF%99%E9%87%8C%E7%9A%84%E8%8C%83%E5%9B%B4%E4%B8%8D%E6%98%AF%E7%8B%AD%E4%B9%89%E4%B8%8A%E7%9A%84%E8%BF%9E%E7%BB%AD%E7%89%87%E6%AE%B5%E3%80%82]
#1.切片形式形如 a=[0,1,2,3,4,5,6,7,8,9] a[start:stop]----->注意这里表示的是一个前闭后闭开的切片操作 a[2:3]------->[2] #注意当切片的区间超过索引的有效值时,并不会报错,会根据是否所表达的操作趋势进行截断操作 a[100,-1]--------->0 a[-100,5]---------->[0,1,2,3,4] #如果start的位置比stop还靠后怎么办?Python还是不会抛出异常,而是直接返回空序列: #2.缺省形式的切片操作 a[:100]----------->[0,1,2,3,4,5,6,7,8,9]默认缺省的情况下 start无穷小,stop无穷大 #3.带step的切片操作a[start:stop:step] 当step为正整数的情况下: a[1:6:2]----------->[1:3:5]注意stop对应的值仍然是限定的值 但step为负数的情况下:不缺省的索引与上述的索引一致,缺省的情况下,注意是反方向使得索引切片的范围最大 a[2::-1]----------->[2,1,0] a[::-1]------------->[9,8,7,6,5,4,3,2,1,0] -
解决超时问题的笨方法
- 对于经常需要访问到的数据先初始化,相当于制造出reference表,不用每次都要初始化该表
- 第二种笨方法就是一定要使用break,避免无用的循环操作,
- 可以使用上面我所说的自定义input等函数
- 如果还不行尽量尝试使用就是算法问题,有时候不是暴力求解而是找规律的
-
python的开立方有问题
print(1000**(1/3))#这个结果应该是10的,可是却得到了9.9999998解决办法有使用numpy库中的函数
但是竞赛不能使用非自带库,搜了全网没有找到合适的,可以在math.floor(num)后在此加1判断一下,我目前只能想到这种方法
-
int与math.floor的区别:数值上人类看起来差不多,但是int会改变数据的类型,而floor知识保留整数部分,数的类型没有改变
-
我人傻了,既是平方数又是立方数那么这个数也一定是6(2与3的最小公倍数)次方数
-
不要把问题东边一榔头,右边一榔头的想问题,说了不要怕超时,你TM用python还怕超时,那不是搞笑来吗,注意抓住问题的本质,比如整除的问题就不用思考别的,不要去拼凑答案,有时解题的思路都在题目里,按照题目要求去做,保准没错
-
冒泡排序你还会写吗?
# 冒泡排序 from sys import stdin def input(): return stdin.readline().strip() data = list(map(int, input().split())) for i in range(len(data)): # control times of iteration # becasuse of adjacent elements compare will increment itself proposingly for j in range(0, len(data)-i-1): if data[j] > data[j+1]: data[j], data[j+1] = data[j+1], data[j] print(" ".join((list(map(str, data))))) -
python中排序解析:
1.列表中自带的sort函数
a[4,3,2,1] a.sort()该方法有以下特点:原地排序,无返回值(返回值为NONE)
拓展
- 自定义比较方法python3取消了。。。。。但是 \(cmp_to_key\)函数可以将老式的比较函数转化为 key 函数
#寻找m中元素所组成数值的最大值 import functools m=[4,3,2,1] m.sort(key=functools.cmp_to_key(lambda x,y:int(str(y)+str(x))-int(str(x)+str(y))))#注意是为正执行交换的策略 print("".join([str(i) for i in m]))- 自定义键函数(key=function())
#比较列表m中的元素距离2的大小 m=[4,3,2,1] l=sorted(m,key=lambda x:abs(x-2)) print(l) 键函数与比较函数的区别:
-
键函数是通过将比较对象通过该函数替换得到新值,在通过新值进行默认大小的\(cmp\)得到两个元素间的大小关系(而且key只支持一个参数不要)
-
比较函数则是通过比较两个元素,通过返回值来判断是否要执行交换策略,如果返回值为正数那么就执行交换策略(比较函数支持两个参数)由于目前的python版本不支持\(cmp\)函数了,我们可以通过\(functools\)中的\(cmp_to_key\)来实现,最方便的是写一个lambda函数来执行
- 排序的reverse功能当reverse为True的时候说明执行倒序(从大到小)
1.内建sorted()函数
可以对可迭代对象进行排序,非原地,返回值是一个列表
有以下特点:
- 对于字符串会list化后按照ASCII码进行比较
- 对于dict如果没有使用items方法,那么只是对key值进行默认排序,返回的也是key值的不带value
- 其他功能与sort()差不多,参考上面所述 -
利用python自带的operator库实现更多功能
operator模块自带运算的映射功能,包含了 许多+-*/的映射函数,下面重点介绍其中的三个类:
- attrgettter
- itemgetter
- methocaller
- attrgetter:
返回从其操作数所获取的attr可调用对象,如果请求多个属性,则返回属性元组,常用与不支持原生比较的对象
- itemgetter
返回一个可调用对象,该操作对象使用操作数的__getitem__()方法从其操作数中获取项,如果制定了多个项,则返回一个查找元组------->就是获取指定域中的对象,所指定的元素一定是可以被下标索引的(经过不知名人士的测试,itemgetter(),比自定义的匿名函数大数据量下更高效点。。。。)
from operator import itemgetter, attrgetter a = [1, 0, 8, 6, 3] b = {1: 4, 2: 8, 3: 4, 8: 2} # print(b.items()) #保留下标索引对a进行排序 print(sorted(enumerate(a), key=lambda x: x[1])) print(sorted(enumerate(a),key=itemgetter(1))) #对字典b进行排序根据对应的value print(dict(sorted(b.items(),key=lambda x: x[1]))) print(dict(sorted(b.items(),key=itemgetter(1))))- methocaller
方法调用器感觉用处不大,主要是对于某些方法的调用不需要实例化,直接通过方法调用器指定参数即可使用,也可以创建operator.methocaller(arg1,arg2,arg3)生成调用对象来使用
-
利用python自带的functools模块
模块适用于所有可调用对象
- partial:偏函数实现函数功能的动态添加与修改:( partial() 是被用作 “冻结” 某些函数的参数或者关键字参数,同时会生成一个带有新标签的对象(即返回一个新的函数)。 )
from functools import partial #八进制转换为十进制 O2D=partial(int,base=8) print(O2D('10'))-
update_wrapper
-
wraps
-
reduce:执行归约操作会将上一次迭代后的参数作为输入之一,继续执行下去
from functools import reduce a='helloworld' b=[1,2,3,4] #执行字符串反转 print(reduce(lambda x,y:y+x,a)) #执行列表数之和 print(reduce(lambda x,y:x+y,b))- cmp_to_key:见上文
- lru_cache
- singledispatch
-
分支判断会降低你的代码执行效率,尽量减少判断,加快代码的执行效率
-
判断一个数是否是偶数可以通过:
a=5
if 1-(a&1):
print("偶数")
else:
print('奇数')
-
主要python中的参数传递是引用赋值,还是值拷贝,如果参数类型是mutable(list等可变类型)那么就是引用赋值,会随着改变而改变,如果参数类型是不可变的(字符串,元组)那么就是值传递,不会随着改变而改变
-
ps解决list调用参数改变,可以通过深拷贝
import copy a=[1,2,3,4] b=a#这是引用赋值,可以说是浅拷贝 b=copy(a)#这是引用赋值,可以说是浅拷贝 b=copy.deepcopy(a)#这是深拷贝不会随着改变而改变
-
-
有时候题目给你的条件都是有用的比如说 Absent Remainder这题目中就给了你一些比较奇怪的限制比如说一定能够保证有解,而且解的数目会是math.floor(len(num)//2),这就很奇怪了,如果按照题目中的叙述,进行比较的话,那么一定会超时的,因为你需要遍历比较,其实这题不需要进行比较因为,在一个sequence中(递减的)利用余数一定被除数小就能直接写出答案不需要遍历,注意啊这些技巧的分析! 、
-
复习期末考试的时候发现的一个有趣的函数,chr(unicode of char ) ord(specific char),由字符ASCII进行快速的转换操作!
-
zip函数将可迭代对象作为参数,将对象中对应的元素打包成为一个元组,然后返回zip迭代对象
#通过zip函数可以解决list列表对获取指定行数据简单,指定列数据难的问题 a=[[1,2,3],[4,5,6]] row1_data=a[1-1] col1_data=list([*zip(*a)][1-1])#利用zip的对应关系解决该问题 -
python中使用set去重后,如何恢复原有的顺序:
a=[1,2,3,1,2,2] b=list(set(a)) b.sort(a.index) -
python列表生成式以及匿名函数里的条件判断怎么用
a=[1,2,3,4] b=[i**i for i in a if i%2==0] c=[i*i if i%2!=0 else i+1 for i in a ] d=list(map(lambda x : x**2 if x %2!=0 else x,a))ps:单独一个条件(不带else)写在循环的后面,否则写在for循环的前面,if 前面表示条件成立执行的语句,else的与正常情况下一致
-
python实现sum的自定义功能可以使用functools里的reduce功能来实现
-
python中的字符串不支持索引功能,需要转为list就可以进行索引了,进行数据输入的时候也尤其需要注意。
-
Python 中null 与none的区别:
null:是空 不表示具体的值(也就是无法赋值 没有内存空间的存在 相当于空指针)
none:一种特殊的值,空值 系统会为该值的变量 开辟内存空间 可以自由的使用

浙公网安备 33010602011771号