python小积累

1. 输出间隔及末尾控制

设置标志flag

  • 例如:要求输出参数之间以空格分隔,且末尾不能有空格

flag = False
==== 循环体 ====
print((" " if flag == True else “”) + “{}”.format(x), end="")
flag = True

=== 循环体结束 ===

  • 在无限循环while循环体设置标志也非常有用,通过修改标志,可以建立循环体出口。
2. 判断素数

#实例①#
#实例②#
初阶版:

import math
def isPrime(n):
	if n <= 1:
		return False
	for i in range(2, n):
		if n % i == 0:
			return False
	return True

中阶版:
根据数学知识,在遍历判断时仅需判断至根号下n,可以减少一半的计算量。

import math
def isPrime(n):
	if n <= 1:
		return False
	for i in range(2, int(math.sqrt(n)) + 1):
		if n % i == 0:
			return False
	return True

高阶版:
除了2以外的所有偶数都不是素数,除了3以外能被3整除的都不是素数,以此类推。大大减少素数判断次数。
初始化标志列表,其中各个元素值都置为1。
将上述规律中不是素数的标志均置为0。

将处理过程分为两部分:
①修改标志列表中的值
②移动“指针”p至下一个素数

def prime(n):
    flag = [1]*(n+2)
    p=2
    while(p<=n):
        print(p)
        for i in range(2*p,n+1,p):
            flag[i] = 0
        while 1:
            p += 1
            if(flag[p]==1):
                break

运行结果:

>>> prime(20)
2
3
5
7
11
13
17
19

思考:为什么要构建大小为n+2的列表?
因为素数最小从2开始,为使序号匹配便于遍历flag,如上例中,要求小于等于20的素数,那么要保证flag[20]有效,根据切片性质,采用range方法,必须是range(:21)才能行得通。因此flag可遍历的序号应该是0-20,即flag大小是n+1。最终大小设置为n+2的原因是考虑到外层while循环退出,所以最后设置一个“哨兵”

3. 计算最大公约数

一、欧几里得算法(辗转相除法)
在这里插入图片描述

def gcd(a, b):
	return (a if b == 0 else gcd(b, a % b))

在math模块中已经封装了gcd方法~
可以直接使用 math.gcd(a, b)

求最大公约数的思想源于2300多年前的欧几里得算法~

二、连续整数算法
取两数中较小值,递减判能否整除两数
在这里插入图片描述

4. 多条件排序

sorted()方法中的参数 key 可以附多个条件
格式:key=lambda <序列名> : (条件1,条件2, 条件3……)

>>> s1 = [['10000011', '85', '80'], ['10000003', '85', '80'], ['10000004', '80', '85'], ['10000013', '90', '99']]
>>> s2 = [['10000005', '82', '77'], ['10000006', '83', '76'], ['10000007', '90', '78']]
>>> s1 = sorted(s1, key=lambda s:(eval(s[1])+eval(s[2]), eval(s[1])), reverse=True)
>>> s2 = sorted(s2, key=lambda s:(eval(s[1])+eval(s[2]), eval(s[1])), reverse=True)
>>> s1
[['10000013', '90', '99'], ['10000011', '85', '80'], ['10000003', '85', '80'], ['10000004', '80', '85']]
>>> s2
[['10000007', '90', '78'], ['10000006', '83', '76'], ['10000005', '82', '77']]
5. 具有欺骗性的的round()

在仅保留一位小数时注意遵循整数部分“奇进偶弃”,其他情况正常

>>> round(10.5)
10
>>> round(11.5)
12
>>> round(12.5)
12
>>> round(10.55, 1)
10.6
>>> round(10.65, 1)
10.7
>>> round(11.55, 1)
11.6

可以使用decimal模块中的quantize()方法来解决~

>>> from decimal import Decimal
>>> x = Decimal('5.16')
>>> x.quantize(Decimal('0.0'))
Decimal('5.2')
>>> x = Decimal('5.14')
>>> x.quantize(Decimal('0.0'))
Decimal('5.1')
>>> x = Decimal('4.15')
>>> x.quantize(Decimal('0.0'))
Decimal('4.2')
6. 保留小数位边界情况的进位变号问题

可以参照B1051

7. 异常处理try-except-else

如果处理异常的except后对应多个异常情况,应采用括号的格式

try:
	......
except (IndexError, TypeError, ...):
	......
else:
	......
8. 在编程考试中输入数据的处理

有时输入给出多组数据,并不一定要急于读入存储
可以逐个组读入并同时进行相应处理
相比全部读入再遍历处理显得较为明朗~
具体参见B1061

9.sorted()方法的妙用
10.正则表达式的应用

在这里插入图片描述

def func8():
    import re
    ls = eval(input())
    lis = re.findall('[0-9]+', ls)
    result = []
    for num in lis:
        if 3 <= len(num) <= 5:
            result.append(int(num))
    print(sorted(result, key=lambda x:sum(result)/x, reverse=False))

func8()
11.计算矩阵乘积和

第三方库numpy中的@矩阵乘法可以直接搞定。

那么如果不用第三方库呢?

matrix1 = eval(input())
matrix2 = eval(input())

matrix2R = [[row[i] for row in matrix2] for i in range(len(matrix2[0]))] #将第二个矩阵转置

result = []
for i in range(len(matrix1)): #用i控制遍历matrix1的列表元素
    ls = [] #用于存储结果矩阵中的矩阵元素
    temp = 0 #用于存储结果矩阵中矩阵元素中的值
    for j in range(len(matrix2R)): #用j控制遍历matrix2R的列表元素
        for k in range(len(matrix2R[0])): #用k遍历列表元素中的值
            temp += matrix1[i][k]*matrix2R[j][k] #计算对应矩阵元素乘积和
        ls.append(temp) #将结果添加到新的矩阵元素中
        temp = 0
    result.append(ls)

print(result)

示例:

==== RESTART ====
[[1,2,3,4]]
[[1],[2],[3],[4]]
result= [[30]]
>>> 
==== RESTART ====
[[1,1,1],[2,2,2],[3,3,3]]
[[1,2,3],[1,2,3],[1,2,3]]
result= [[3, 6, 9], [6, 12, 18], [9, 18, 27]]
12.列表去重后排序(按原列表元素顺序)
name_lst = input().split(',')                         # 输入的字符串节分为列表
name_no_duplicate = list(set(name_lst))               # 去除重复的元素
print(sorted(name_no_duplicate, key=name_lst.index))  # 按名字在原列表中出现的顺序排序

输入
Calvin,bob,ada,McCord,Smith,Babbs,Calvin,Smith
输出
[‘Calvin’, ‘bob’, ‘ada’, ‘McCord’, ‘Smith’, ‘Babbs’]

13.分解质因数

什么是质因数?

n = eval(input())
ls = []
while n!=1:
    for i in range(2, n+1):
        if n%i == 0:
            n //= i
            ls.append(i)
            break

或使用递归?

ls = []
def f(n):
    for i in range(2, n+1):
        if n%i == 0:
            ls.append(i)
            return f(n//i)
14.找完数

完数,即除本身以外,等于所有因子之和

m,n=map(int,input().split())
count=0
for i in range(m,n+1):
    s=[k for k in range(1,i) if i%k==0] #这里因子不包括这个数本身
    if sum(s)==i:
        s.sort()
        print("%d = %s"%(i," + ".join(map(str,s))))
        count+=1
if count==0:
    print("None")

如何解决超时?
如下:

m,n = map(int,input().split())
cnt = 0
for k in range(m,n+1):
    factor = [1]
    for i in range(2, int(k**0.5)+1):
        if k%i == 0: #可以整除i,i是一个因子
            factor.append(i)
            if k//i not in factor: #除以i之后的商若不在因子列表中,则补充添加,这里区别于质因数分解,因此for语句的范围可以大大缩小
                factor.append(k//i)
    if sum(factor) == k:
        factor.sort() #注意!!!为什么要重新排序?上述区分点的原因
        cnt+=1
        print(str(k)+" = "+" + ".join(map(str,factor)))
if cnt == 0:
    print('None')
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值