python 练习题1

 

个人博客       https://www.wzstyle.cn/

 

1、求100(100000)以内的素数:

  • 从2开始到自身的数-1中找到一个能整除的 => 从2开始到自身开平方的数中找到一个能整除的
  • 一个合数一定可以分解成几个素数的乘积,也就是,一个数如果能被一个素数整除就是合数
import datetime
n = 100000
start = datetime.datetime.now()
count = 2 #隐含着2和3
primenumbers = [3] #下面代码要求列表中至少得有一个质数

for x in range(5,n,2):    #舍弃掉所有偶数
    edge = int(x ** 0.5)
    flag = False   #不是质数
    for i in primenumbers:
        if i > edge:
            flag = True
            break #是质数
        if x % i ==0:    #与质数取模
            break   #是合数
    if flag:
        count +=1   #质数
        primenumbers.append(x)
        
delta = (datetime.datetime.now() - start).total_seconds()
print(delta,count)

孪生素数性质

  • 大于3的素数只有6N-1和6N+1两种形式,如果6N-1和6N+1都是素数称为孪生素数
  • 其实测试的都是6的倍数的前后的数字,这些数字一定是奇数
primenumbers = [3,5]
count = 3  #质数包含2,3,5
n = 100000
x = 7
step = 4

while x<n:
    if x % 5 !=0:
        flag = False   #不是质数
        edge = int(x ** 0.5)
        for i in primenumbers:
            if i > edge:
                flag = True   #是质数
            if x % i ==0:
                break      #是合数
        if flag:
            count += 1
            primenumbers.append(x)
    x += step
    step = 4 if step ==2 else 2
print(count)

2、计算杨辉三角前6行

  • 第n行有n项,n是正整数
  • 第n行数字之和为2**(n-1)
#方法1

triangle = [[1],[1,1]]
n = 6
for i in range(2,n):
    pre = triangle[i-1]  #前一行    [1,1] 
    cur = [1]   #[1,2]
    for j in range(1,i):   #1
        cur.append(pre[j-1] + pre[j])   #1+1
    cur.append(1)   #[1,2,1]
    print(cur)
    triangle.append(cur)   #[[1],[1,1],[1,2,1]]
print(triangle)
#方法2 对称

n = 6

for i in range(n):
    cur = [1] * (i+1)   #一次开辟内存空间,左右2端的1也不用算了   
    for j in range(1,i//2+1):   #索引向右平移一位  
        value = pre[j-1] + pre[j]   
        cur[j] = value
        if i != 2*j:
            cur[-j-1] = value
    print(cur)
    pre = cur

-------------------------------
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]

3、一个10进制正整数数字,打印每一位数字及其重复的次数

num = '11234555'
counter = [0]*10
for x in num:
    counter[int(x)] += 1
for i in range(len(counter)):
    if counter[i]:
        print('the count of {} is {}'.format(i,counter[i]))

--------------------------
the count of 1 is 2
the count of 2 is 1
the count of 3 is 1
the count of 4 is 1
the count of 5 is 3

4.猴子吃桃问题:猴子第一天获得了若干个桃,当即吃了一半,不过瘾又多吃了一个。之后每天都吃了前一天剩下的一半零一个。到第10天想吃时,发现只剩下了一个桃子。求第一天获得桃子的总数量。

peach = 1
for i in range(9):
    peach=2 * (peach + 1)
print(peach)
-----
1534个

5.求杨辉三角第n行第k列的值

#算法1
m=9
k=5
pre=None
for i in range(m):
    row = [1]*(i+1)
    
    for j in range(1,i):
        row[j]=pre[j-1]+pre[j]
    pre=row
    
print('----')
print(row)
print(row[k-1])
----
[1, 8, 28, 56, 70, 56, 28, 8, 1]
70

6.数字统计:随机产生10个数字,取值范围是[1,20];统计重复和不重复的数字是什么,有几个。思路:例如11,7,5,11,6,7,4,先拿出11依次从第二个数字开始比较,发现11就把对应索引标记,这样比较一趟就知道11是否重复,哪些地方重复。第二趟使用7和其后的数字依次比较,发现7就标记,当遇到以前比较过的11位置的时候,其索引已经被标记为1,再在对应索引上加1,就可知道重复几次。

import random
nums=[]
for _ in range(10):
    nums.append(random.randrange(21))
    
nums=[5, 8, 6, 4, 9, 9, 15, 15, 4, 13]
print('origin numbers = {}'.format(nums))
print()

length=len(nums)
samenums=[]       #记录相同的数字
diffnums=[]       #记录不同的数字
states=[0]*length #记录不同的索引异同状态

for  i in range(length):
    if states[i] !=0:
        continue
    count=0  #假定没有重复
    
    for j in range(i+1,length):
        if states[j] !=0:
            continue
        if nums[i] == nums[j]:
            count += 1
            states[j]=count
        
    if count: #有重复
        states[i]=count + 1
        samenums.append((nums[i],states[i]))
    else:
        diffnums.append(nums[i])
print('same numbers={1},count={0}'.format(len(samenums),samenums))
print('diff numbers={1},count={0}'.format(len(diffnums),diffnums))
print(states)
-----
origin numbers = [5, 8, 6, 4, 9, 9, 15, 15, 4, 13]
same numbers=[(4, 2), (9, 2), (15, 2)],count=3
diff numbers=[5, 8, 6, 13],count=4
[0, 0, 0, 2, 2, 1, 2, 1, 1, 0]

7、格式输出。编写如下格式的上下三角,要求数字对齐。

#上三角方法1
def triangle_print(n):
    g=(str(i) for i in range(n,0,-1))
    tail = ' '.join(g)
    width = len(tail)
    
    for i in range(1,n):
        line = ' '.join(map(str,range(i,0,-1)))
        print('{:>{}}'.format(line,width))
    print(tail)
triangle_print(12)


#方法2
def triangle_print(n):    #右对齐 切片方法
    tail = ' '.join(map(str,range(n,0,-1)))
    width = len(tail)
    
    start = -1
    step = 2   #跨越10,100,1000等时候,要调整步长
    points={10**i for i in range(5)}
    
    for i in range(1,n):
        line=tail[start:]
        if (i+1) in points:
            step += 1
        start -= step
        print('{:>{}}'.format(line,width))
    print(tail)
triangle_print(12)

#方法3
def triangle_print(n):
    tail = ' '.join(map(str,range(n,0,-1)))
    width = len(tail)
    #print(tail)
    
    for i in range(-1,-width,-1):
        if tail[i] ==' ':
            print('{:>{}}'.format(tail[i+1:],width))
    print(tail)
triangle_print(12)
#下三角
def triangle_print(n):
    tail = ' '.join(map(str,range(n,0,-1)))
    width = len(tail)
    print(tail)
    
    for i,c in enumerate(tail):
        if c == ' ':
            print('{:>{}}'.format(tail[i+1:],width))
triangle_print(12)

-----------------------------------------------------------------------------------

8、实现base64编码

alphabet=b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'   #编码表
print(alphabet)
src='abcd'

def base64encode(src:str,encoding='utf-8')-> bytes:
    ret=bytearray()
    if isinstance(src,str):
        _src=src.encode(encoding=encoding)
    elif isinstance(src,(bytearray,bytes)):
        _src=bytes(src)
    else:
        return b''  #说明转换失败
        
    length=len(_src)
        
    for offset in range(0,length,3):
        triple= _src[offset:offset+3]  
        
        r=3-len(triple)
        if r:
            triple += b'\x00' * r
        #bytes和bytearray都是按照字节操作的,需要转换为整数才能进行位运算
        #将3个字节看成一个整体转成字节bytes,大端模式
        b=int.from_bytes(triple,'big')
        for i in range(18,-1,-6):
            index=b >> i if i==18 else b >> i & 0x3F
            ret.append(alphabet[index])
        if r:
            ret[-r:] = b'=' * r
    return bytes(ret)
#================
import base64  #内建模块
strlist =['a','`','abc','abcd','wzstyle','网子style']
for x in strlist:
    print(x)
    print(base64encode(x))   #这是我们自己写的函数
    print(base64.b64encode(x.encode()))
    print('-'*10)

9、实现一个cache装饰器,实现可过期被清理的功能

import datetime
import time
from functools import wraps
import inspect

def logger(fn):
    print('='*30)
    @wraps(fn)
    def wrapper1(*args,**kwargs):
        start=datetime.datetime.now()
        ret=fn(*args,**kwargs)
        delta=(datetime.datetime.now()-start).total_seconds()
        print(fn.__name__,delta)
        return ret
    return wrapper1

def m_cache(duration):
    def _cache(fn):
        print('-'*20)
        local_cache={}  #每装饰一个函数,都有此函数的独立的cache
        @wraps(fn)
        def wrapper2(*args,**kwargs):
            def _clear(cache):
                expire_keys = []
                for k,(_,stamp) in local_cache.items():
                    now = datetime.datetime.now().timestamp()
                    if now - stamp > duration:
                        expire_keys.append(k)
                for k in expire_keys:
                    local_cache.pop(k)
            _clear(local_cache)

            def make_key():
                target={}   #字典无序
                sig=inspect.signature(fn)
                params=sig.parameters

                target.update(zip(params.keys(),args),**kwargs) #位置传参,变量名称的对应
                target.update(map(lambda k:(k,params[k].default),params.keys()-target.keys()))
                key=tuple(sorted(target.items()))
            key=make_key()

            if key not in local_cache.keys():
                local_cache[key] = fn(*args,**kwargs),datetime.datetime.now().timestamp()
            return key,local_cache[key]
        return wrapper2
    return _cache

@logger
@m_cache(1)    #如果有多个装饰器,装饰过程由近及远   #洋葱式
def add(x=4,y=5):
    print('~'*30)
    time.sleep(2)
    return x+y

print(1,add(4,5))
time.sleep(3)
print(2,add(4))
print(3,add(y=5))
print(4,add(x=4,y=5))
print(5,add(y=5,x=4))
print(6,add())

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值