python小技巧

目录

跳出双重循环

汉诺塔问题:n个盘要移动(2^n) -1

itertools:做全排列的好伙伴!

对于多个数组进行排列

product()

对于同一数组

permutations()   考虑一组内数字的排序,即 1 2 3 与 3 2 1是不同的

combinations()    不考虑一组内的排序,即1 2 3 与 3 2 1 是相同的

combinations_with_replacement()

二分查找内置库:bisect   (前提:有序序列)

集合求和

二分查找

阶乘

求斜率与截距

直线分割平面

datetime 相关库

一.time库

①time.gmtime(秒数)

​ ②time.asctime(日期时间)

time.gmtime与datetime.timestamp 时间戳不同

2.datetime.timestamp (秒数):

3.parse():可将任意形式的时间日期str转换为dateime.datetime          ​

二.datetime库

4.datetime.datetime.strptime('format'):将format格式的str转换为dateime.datetime       (与parse()不同在于读入的格式是人为固定的)

5.d.strftime(format):将dateime.datetime类型转换为指定格式的str

 6.datetime.timedelta()   

等差数列公式

copy库

约数个数定理:求取一个数有多少正约数及正约数之和

关于四舍五入及保留小数点

求组合数C(a,b)

读文件

去重及sort用法 

Collections库的用法:用于字典


跳出双重循环

一旦内部循环break,同时也跳出外层循环

n=3
for i in range(n):
    for j in range(n):
        if j==1:break
    else:continue
    break

如一旦j=1,break跳出内层循环后,不会执行else的内容,而是直接执行else下面的语句,即break

汉诺塔问题:n个盘要移动(2^n) -1

itertools:做全排列的好伙伴!

python itertools功能详解_neweastsun的专栏-CSDN博客_itertools


对于多个数组进行排列

product()

product(iter1,iter2, ... iterN, [repeat=1]);创建一个迭代器,生成表示item1,item2等中的项目的笛卡尔积的元组,repeat是一个关键字参数,指定重复生成序列的次数

    # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
    # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111

对于同一数组

permutations()   考虑一组内数字的排序,即 1 2 3 与 3 2 1是不同

用于全排列

permutations(p[,r]);返回p中任意取r个元素做排列的元组的迭代器

for i in permutations([1, 2, 3], 3):
(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)

注意区分combinations()  与permutations()的差别

combinations()    不考虑一组内的排序,即1 2 3 与 3 2 1 是相同

用于组合

combinations(iterable,r);创建一个迭代器,返回iterable中所有长度为r的子序列,返回的子序列中的项按输入iterable中的顺序排序

note:不带重复 (即列表中的数字选过就不能选了)

for i in combinations([1, 2, 3], 2):
(1, 2)
(1, 3)
(2, 3)

combinations_with_replacement()

同上, 带重复 例子:  (即列表中的数字可以重复选择)

for i in combinations_with_replacement([1, 2, 3], 2):
(1, 1)
(1, 2)
(1, 3)
(2, 2)
(2, 3)
(3, 3)

二分查找内置库:bisect   (前提:有序序列)

转载自:【Python】详解 bisect 模块_闻韶-CSDN博客_bisect.bisect_right

主要应用:

  • 查找: bisect(序列,查找的元素)     返回插入元素的下标,原序列不会发生改变
  • 插入: insort(序列,插入的元素)       返回的是一个新排好序的序列
名称功能
bisect_left()查找 目标元素左侧插入点
bisect_right()查找 目标元素右侧插入点
bisect()同 bisect_right()
insort_left()查找目标元素左侧插入点,并保序地 插入 元素
insort_right()查找目标元素右侧插入点,并保序地 插入 元素
insort()同 insort_right()

left和right只有在序列中存在需要查找的元素时才有不同,因为一个会插在左边,一个会插在右边

例:

如果列表中存在多个元素等于x,那么bisect_left(ls, x)返回最左边的那个索引,此时ls[index2] = x。bisect_right(ls, x)返回最右边的那个索引加1,此时ls[index3] > x。

import bisect
ls = [1,5,5,5,17]
index1 = bisect.bisect(ls,5)
index2 = bisect.bisect_left(ls,5)
index3 = bisect.bisect_right(ls,5)
print("index1 = {}, index2 = {}, index3 = {}".format(index1, index2, index3))

程序运行结果为,

index1 = 4, index2 = 1, index3 = 4

集合求和

给定一个集合s(集合元素数量<=30),求出此集合所有子集元素之和:
(序列元素和)*2^(n-1)


杨辉三角每排数字加和正好为2^(n-1)

二分查找

使用二分查找的特征:

  1. 答案具有单调性; 
  2. 二分答案的问题往往有固定的问法,比如:令最大值最小(最小值最大),求满足条件的最大(小)值等。

    模板:

    当有 X 时这套代码就返回 X 的位置。如果没有 X,就返回 <=x 的数中最大的一个或者 >=x 的数中最小的一个。  

     
求尽可能大的m(m就是最逼近或等于目标值x的那个值):在单调递增序列a中查找<=x的数中最大的一个 

求尽可能小的m:在单调递增序列a中查找>=x的数中最小的一个

#在单调递增序列a中查找>=x的数中最小的一个(即x或x的后继)
while low<high:

  mid=low + (high - low) // 2

  if(a[mid]>=x):
      high=mid
  
  else:
      low=mid+1

#在单调递增序列a中查找<=x的数中最大的一个(即x或x的前驱)
while low<high:

  mid=low + (high - low) // 2

  if(a[mid]<=x):
      low=mid

  else:
      high = mid-1

例题:CSDN

【深基13.例1】查找 - 洛谷

阶乘

import math

math.factorial(n)

求斜率与截距

斜率k = (y2 - y1) / (x2 - x1)       

截距b = (x2 * y1 - x1 * y2) / (x2 - x1)

在应用时注意用/不要用//

直线分割平面

每新增一条线必多一个平面

对于某条新加入的直线而言:与前面已存在的直线相交有多少个不同的交点就新增多少平面

当前新加入的直线与之前已加入的直线集合会产生多少个交点,如果产生了k个交点,则划分的区域就会增加 k+1 个。

(两直线重合不算,可直接去掉一条)

 转载自第十一届蓝桥杯软件类Python组(最新)(试题回忆+部分个人解答)___Pure_white__的博客-CSDN博客_第十一届蓝桥杯python试题a

datetime 相关库

一.time库

time.gmtime(秒数)

把从格林威治时间1970年01月01日00时00分00开始的秒数转换为struct_time

 ②time.asctime(日期时间)

把系统识别的struct_time转换为可读的str的日期

两者结合起来用: 

time.gmtime与datetime.timestamp 时间戳不同

2.datetime.timestamp (秒数)

datetime.timestamp 时间戳是从北京时间1970-01-01 08:00:00开始计算的,因此要得到从格林威治时间1970-01-01 00:00:00算的日期,应该减去一个8小时

3.parse():可将任意形式的时间日期str转换为dateime.datetime          

from dateutil.parser import parse

 parse()常与datetime库结合起来用

二.datetime库

%a 星期的简写。如 星期三为Web
%A 星期的全写。如 星期三为Wednesday
%b 月份的简写。如4月份为Apr
%B月份的全写。如4月份为April 
%c:  日期时间的字符串表示。(如: 04/07/10 10:43:39)
%d:  日在这个月中的天数(是这个月的第几天)
%f:  微秒(范围[0,999999])
%H:  小时(24小时制,[0, 23])
%I:  小时(12小时制,[0, 11])
%j:  日在年中的天数 [001,366](是当年的第几天)
%m:  月份([01,12])
%M:  分钟([00,59])
%p:  AM或者PM
%S:  秒([00, 59])

%w:  今天在这周的天数,范围为[0, 6],6表示星期天

%U:  周在当年的周数(当年的第几周),星期天作为周的第一天
%W:  周在当年的周数(是当年的第几周),星期一作为周的第一天

%x:  日期字符串(如:04/07/10)
%X:  时间字符串(如:10:43:39)
%y:  2个数字表示的年份
%Y:  4个数字表示的年份
%z:  与utc时间的间隔 (如果是本地时间,返回空字符串)

原文链接:https://blog.csdn.net/wirelessqa/article/details/7973121

4.datetime.datetime.strptime('format'):将format格式的str转换为dateime.datetime       (与parse()不同在于读入的格式是人为固定的)

5.d.strftime(format):将dateime.datetime类型转换为指定格式的str

 6.datetime.timedelta()   

具体用法见Python datetime指南:教你如何处理日期和时间(附试题+答案)_Python大本营的博客-CSDN博客

# Input
import datetime
d1 = datetime.date(1869, 1, 2)
d2 = datetime.date(1869, 10, 2)
# Solution
delta = d2 - d1  # timedelta
# Get all dates 
dates_btw_d1d2 = [(d1 + datetime.timedelta(i)) for i in range(delta.days + 1)]
n_saturdays = 0
for d in dates_btw_d1d2:
    n_saturdays += int(d.isoweekday() == 6)
print(n_saturdays)    

等差数列公式

Sn=n(a1+an)/2 或Sn=a1*n+n(n-1)d/2

an=a1+(n-1)d

注意:差为0也是等差数列

冒泡排序的排序最坏的交换次数:count=(n*(n-1)) / 2

copy库

浅拷贝:只拷贝了最外层,只有最外层相互不受影响。因此里面层变化会跟着一起变化。

l2=copy.copy(l1)

深拷贝:完全拷贝,两变量不互相影响

l2=copy.deepcopy(l1)

约数个数定理:求取一个数有多少正约数及正约数之和

适用于阶乘很大或者给出一个很大的数拆解成几个小项后求其约数个数及和

缺点:不能够求得每一个约数是什么

题目:阶乘约数

求约数个数:

求约数之和:

代码 

n=int(input())
def su(x):                         #判断质数
    if x==1 or x==0:return False
    for i in range(2,int(math.sqrt(x))+1):
        if x%i==0:return False
    return True

l=[]
for i in range(2,n+1):     #求出一个对于较小的数来说,其所有质因数
    if su(i):
        l.append(i)

num=[0 for i in range(len(l))]

#分解质因数,从而求得各个质数的次方
for j in range(len(l)):      
    while n:
        if n%l[j]==0:
            num[j]+=1
            n//=l[j]
        else:break
                
#求正约数的个数
ans=1
for i in num:
    if i!=0:
        ans*=(1+i)
print(ans)

#求所有正约数之和
s=1
for i in range(len(l)):
    now=0
    if num[i]!=0:
        for j in range(num[i]+1):
            now+=l[i]**j
        s*=now
        
print(s)

关于四舍五入及保留小数点

用format:(遵循四舍五入原则)

print("这种方式可以同时控制不同的数四舍五入的位数{:.3f}与{:.2f}".format(6.66555,7.4243))

>>>'这种方式可以同时控制不同的数四舍五入的位数就是6.666与7.42'

round()遵循的是四舍六入次偶进

详见:python 保留若干位小数——format与round区别_lishuaigell的博客-CSDN博客

求组合数C(a,b)

def C(a,b):   #a为上限,b为下限
    ans=1
    for i in range(a):
        ans*=b/a
        b-=1
        a-=1
    return ans

读文件

128.29  88  
251.03   80  
208.39  75  
128.88  75  
 62.06   90  
225.87  75  
 12.89  75  
 34.28  75  
 62.16  58  
129.12  50  
218.37  50  
289.69  80 
file = open('data.txt', 'r')
l=f.read()
a=[]
for i in l.splitlines():
    s=i.split()
    a.append(s)

去重及sort用法 

 python 列表去重及sort用法_?Cyan_的博客-CSDN博客_python sorted去重

Collections库的用法:

1.Counter:用于字典

Python collections模块之Counter()详解_chl183的博客-CSDN博客_counter

from collections import *

1.Counter (数数和排序)
 比如分析文本中每个单词出现过的次数,并只保留出现次数最高的若干个。
 Counter是一个dict子类,主要是用来对你访问的对象的频率进行计数(按次数排序)
 elements():返回一个迭代器,每个元素重复计算的个数,如果一个元素的计数小于1,就会被忽略。
 most_common([n]):返回一个列表,提供n个访问频率最高的元素和计数,当次数相同,按照原字典顺序输出
 subtract([iterable-or-mapping]):从迭代对象中减去元素,输入输出可以是0或者负数
 update([iterable-or-mapping]):从迭代对象计数元素或者从另一个 映射对象 (或计数器) 添加。



a='abcdeec'
b=Counter(a)
print(b)
print(dict(b))
print(list(b.elements())) 
print(b.most_common(2))

print()
e='hello world world'
e=Counter(e.split())
print(e)

>>>得到
Counter({'c': 2, 'e': 2, 'a': 1, 'b': 1, 'd': 1})  #按次数排序
{'a': 1, 'b': 1, 'c': 2, 'd': 1, 'e': 2}   #按原来字典顺序
['a', 'b', 'c', 'c', 'd', 'e', 'e'] 
[('c', 2), ('e', 2)]

Counter({'world': 2, 'hello': 1})


dic1 = {'a': 3, 'b': 4, 'c': 0, 'd': -2, "e": 0}
print(Counter(dic1))
print(list(Counter(dic1).elements()))
#结果:
#Counter({'b': 4, 'a': 3, 'c': 0, 'e': 0, 'd': -2})
#['a', 'a', 'a', 'b', 'b', 'b', 'b']
2.collections下的函数:defaultdict()


s = [('NC', 'Raleigh'), ('VA', 'Richmond'), ('WA', 'Seattle'), ('NC', 'Asheville')]
d=defaultdict(list)
for k,v in s:
    d[k].append(v)
print(d)
#若查询d中不存在的key值时,对于list来说会返回[]
d['hah']


>>>得到
defaultdict(<class 'list'>, {'NC': ['Raleigh', 'Asheville'], 'VA': ['Richmond'], 'WA': ['Seattle']})

[]

同理,对于defaultdict(str),不存在的key值返回''
defaultdict(int),不存在的key值返回0

2.用于队列deque()

Python collections模块之deque()详解_chl183的博客-CSDN博客_deque()

rotate(n)

rotate(n), 从右侧反转n步,如果n为负数,则从左侧反转。
d.rotate(1) 等于 d.appendleft(d.pop())

from collections import deque

st = "abbcd"
dst = deque(st)
dst.rotate(2)  #右侧两个反转到左边
print(dst)
dst.rotate(-2)  #左侧两个反转到右边
#结果:
#deque(['c','d', 'a', 'b', 'b'])
#deque(['b', 'c', 'd', 'a', 'b'])

maxlen(n)

只读的属性,deque限定的最大长度,如果无,就返回None。
当限制长度的deque增加超过限制数的项时, 另一边的项会自动删除

from collections import deque
dst = deque(maxlen=2)
print(dst)
dst.append(1)
dst.append(2)
print(dst)
dst.append(3)
print(dst)
dst.appendleft(4)
print(dst)
#结果:
#deque([], maxlen=2)    #初始就只能是空
#deque([1, 2], maxlen=2)  
#deque([2, 3], maxlen=2)  #右边添加了3,故原本左1的1删掉
#deque([4, 2], maxlen=2)  #左边添加了4,故原本右1的3删掉

pop()、popleft():队列中的pop不能指定index

二叉树

(1)完全二叉树——只有最下面的两层结点度小于2,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树;(只有底层是不满的)

(2)满二叉树——除了叶结点外每一个结点都有左右子叶且叶结点都处在最底层的二叉树。(比完全二叉树更满)

对于上述两种树:

第i层最后一个结点下标为(2^i)-1  (i从1开始。。。)

对于完全二叉树:最后一层可以有的结点数为:1~2^(i-1)

for if esle的一句话使用

lis_s = [word if is_endwith_s(word) else'666'for word in lis

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值