python学习_董付国老师python培训内容1,为大佬打call

本文所有代码思路均为董付国老师所有,其他为笔者整理以及听课笔记

一、数字黑洞

方法一:

from string import digits  #digits库有数字0-9 十个数字
from itertools import combinations #生成组合,为元组形式

flag=False
for item in combinations(digits,4): #数字0-9中任选4个不同数字的排列组合,这是一个元组
    times=0
    while True:
        #当前选择的4个数字能够组成的最大数和最小数
        big=int(''.join(sorted(item,reverse=True))) #降序排列,大在前小在后
        little=int(''.join(sorted(item)))#默认升序排列
        difference=big-little
        times=times+1
        #如果最大数和最小数相减得到6174就退出
        #否则就对得数的差重复这个操作
        #最多7次,总能得到6174
        if difference==6174:
            if times>7:
                flag=True
                print(times) #这里不会输出,因为次数不超过7次
            break  #因为外面有死循环,必须break
        else:
            item=tuple(str(difference))
if not flag:
    print("猜想正确,得到6174,次数不超过7次")

方法二:

for num in range(1000,10000):#前闭后开
    #数字字符串变为集合后长度不变,表示各个数字不相同
    item=set(str(num))  #变成集合,去掉相同数字,可能只有1个2个3个4个元素
    if len(item)!=4:  #如果集合元素不是4个
        continue    #接下来的程序不运行,检查下一个数字
    times=0
    #print(num)
    while True:
        #当前选择的4个数字能够组成的最大数和最小数
        big=int(''.join(sorted(item,reverse=True))) #降序排列,大在前小在后
        little=int(''.join(sorted(item)))#默认升序排列
        difference=big-little
        times=times+1
        #如果最大数和最小数相减得到6174就退出
        #否则就对得数的差重复这个操作
        #最多7次,总能得到6174
        if difference==6174:
            if times>7:
                flag=True
                print(times) #这里不会输出,因为次数不超过7次
            break  #因为外面有死循环,必须break
        else:
            item=tuple(str(difference))

二、水仙花数

1.普通的水仙花数

n=int(input('请输入位数:'))  #input输入为字符串
for num in range(10**(n-1),10**n): #range左闭右开区间 
    #先用str把这个数字num变成字符串,再用map把每个字符变成整数
    if sum(map(lambda i:int(i)**n,str(num)))==num:
        print(num)

#print(*map(str(num))) 整数
#print(*str(num)) 字符串

2.增加判断输入数据类型

#增加判断输入数据类型
while True:
    n=input("请输入位数:")
    if n.isdigit():
        n=int(n)
        break
    else:
        print("不对,必须输入整数,",end="")
for num in range(10**(n-1),10**n): #range左闭右开区间 
    #先用str把这个数字num变成字符串,再用map把每个字符变成整数
    if sum(map(lambda i:int(i)**n,str(num)))==num:
        print(num)

三、报数游戏(约瑟夫环)

方法一:

def demo(lst,k):
    #切片,以免影响原来的数据
    t_lst=lst[:]
    #游戏一直进行到只剩下最后一个人
    num=len(t_lst) #num总人数
    for i in range(num-1): #要踢掉n-1个人
        for j in range(k-1):
            t_lst.append(t_lst.pop(0)) #不出圈,补上尾部
        t_lst.pop(0)
    #游戏结束
    return t_lst[0]

lst=list(range(1,11))
print(demo(lst,3))

方法二(better)用cycle:

#用cycle 会自动形成一个圈
from itertools import cycle
def demo(lst,k):
    #切片,以免影响原来的数据
    t_lst=lst[:]
    #游戏一直进行到只剩下最后一个人
    while len(t_lst)>1:
        print(t_lst)
        c=cycle(t_lst)
        for i in range(k):
            t=next(c)
        print('弹出数为:',t)
        #一个人出圈,圈子缩小
        index=t_lst.index(t)
        t_lst=t_lst[index+1:]+t_lst[:index]
        
    
    #游戏结束
    return t_lst[0]

lst=list(range(1,11))
print(demo(lst,3))

四、检测与对抗垃圾邮件检测机制

1.垃圾邮件检测机制

def check(s1,s2):
    #sum(map(s1.count,s2)) 统计s1中s2出现的次数
    return sum(map(s1.count,s2))/len(s1)

print(check("这是#一个测\\试邮^%^%件,#内&%%^FG含广","%#\*"))

2.对抗垃圾邮件检测机制1,将长度为2的词交换顺序

from jieba import cut
def swap(word):
    #交换长度为2的单词中的两个字顺序
    if len(word)==2:
        word=word[1]+word[0]
    return word
def antiCheck(text):
    #分词,处理长度为2个单词,然后再连接起来
    words=cut(text)
    return ''.join(map(swap,words)) #对得到的words进行swap处理

text="由于人们阅读时一目十行的特点,有时候个别词语交换"+\
      "一下顺序并不影响,甚至无法察觉这种变化。"+\
      "更有意思的是,及时发现了顺序的调整,也不影响对内容的理解"
print(antiCheck(text))

3.对抗垃圾邮件检测机制2,将30%的长度为2的词交换顺序

from random import random
from jieba import cut
def swap(word):
    #交换长度为2的单词中的两个字顺序
    if len(word)==2 and random()<=0.3:
        word=word[1]+word[0]
    return word
def antiCheck(text):
    #分词,处理长度为2个单词,然后再连接起来
    words=cut(text)
    return ''.join(map(swap,words)) #对得到的words进行swap处理

text="由于人们阅读时一目十行的特点,有时候个别词语交换"+\
      "一下顺序并不影响,甚至无法察觉这种变化。"+\
      "更有意思的是,及时发现了顺序的调整,也不影响对内容的理解"
print(antiCheck(text))

4.对抗垃圾邮件检测机制3,将长度为2的词按unicode编码排序

from jieba import cut
def swap(word):
    #交换长度为2的单词中的两个字顺序
    if len(word)==2:
        word=''.join(sorted(word)) #按unicode编码排序  可这样查看ord('由')
    return word
def antiCheck(text):
    #分词,处理长度为2个单词,然后再连接起来
    words=cut(text)
    return ''.join(map(swap,words)) #对得到的words进行swap处理

text="由于人们阅读时一目十行的特点,有时候个别词语交换"+\
      "一下顺序并不影响,甚至无法察觉这种变化。"+\
      "更有意思的是,及时发现了顺序的调整,也不影响对内容的理解"
print(antiCheck(text))

5.对抗垃圾邮件检测机制4,将长度为2的词按拼音排序

from jieba import cut
from pypinyin import pinyin
def swap(word):
    #交换长度为2的单词中的两个字顺序
    if len(word)==2 :
        word=''.join(sorted(word,key=pinyin)) #按拼音排序  key指定排序规则,内容需为可调用对象
    return word
def antiCheck(text):
    #分词,处理长度为2个单词,然后再连接起来
    words=cut(text)
    return ''.join(map(swap,words)) #对得到的words进行swap处理

text="由于人们阅读时一目十行的特点,有时候个别词语交换"+\
      "一下顺序并不影响,甚至无法察觉这种变化。"+\
      "更有意思的是,及时发现了顺序的调整,也不影响对内容的理解"
print(antiCheck(text))

五、斐波那契数列

#斐波那契数列中的两个数
fibo=[1,1]
#重复接收用户的键盘输入,给出查询结果
while True:
    n=input("请输入一个正整数(0表示结束):")
    #输入0表示结束
    if n==0:
        break
    #对用户的键盘输入做检查,必须为正整数
    try:
        #必须为整数
        n=int(n)
        #必须为正数
        assert n>0  #优化编译会删掉它,小心
    #同时捕捉和处理两种类型的异常
    except (ValueError,AssertionError) as e:
        print("必须输入正整数")
        #跳过后面的代码,直接进入下一次输入
        continue
    length=len(fibo)
    #根据需要动态扩展数列
    if n >length:
        #仅用来控制循环次数的变量可以不起名字,使用一个下划线即可
        for _ in range(n-length):
            fibo.append(fibo[-1]+fibo[-2])
    print(f'第{n}个月的兔子数量是{fibo[n-1]}') #3.6之后可用
    print(f'当前斐波那契数列:\n{fibo}') 

六、进度条

方法一:

from time import sleep
for i in range(1,101):
    sleep(0.1)
    #\r光标回到首位,覆盖前面的内容
    print('\r','.'*(i//5),i,sep='',end='%') #sep默认为空格

方法二:

from time import sleep
for i in range(1,101):
    sleep(0.1)
    #\r光标回到首位,覆盖前面的内容
    print(i,end=' ',flush=True) #不加flush=True会缓存区满了或程序结束后才一次性全部出来

方法三:

from time import sleep
for i in range(1,101):
    sleep(0.1)
    #\r光标回到首位,覆盖前面的内容
    print('.'*(i//5),i,'%',sep='') #输出完后以\n结束,所以会另起一行

七、频次统计

1.一般统计

from random import choices #choices可重复
#from random import sample # sample不重复
from string import digits #digits 0-9 十个数字
# 可重复的1000个数字的拼接
text=''.join(choices(digits,k=1000)) #在0-9里面取数字1000次,可重复
print(text)
for ch in set(text):
    print(ch,text.count(ch))

2.讲解语法用的变化

from random import choices
from string import digits
from operator import itemgetter #itemgetter是个函数

text = ''.join(choices(digits, k=1000))
print(text)

#遍历每一个唯一字符,统计,生成元组
freq = [(ch, text.count(ch)) for ch in set(text)]
#对元组排序,按照元组中下标一的进行降序排序 itemgetter(1)可以获取下标一的字符
freq.sort(key=itemgetter(1), reverse=True)
#相当于freq.sort(key=lambda item:item[1], reverse=True)
#*表达式是序列解包的作用
print(*freq[:3], sep='\n')

3.最推荐使用,符合python的

from random import choices
from string import digits
from collections import Counter #Counter专门用来数数

text = ''.join(choices(digits, k=1000))
print(text)

print(*(Counter(text).most_common(3)), sep='\n')

4.例子,统计license里单词词频

from random import choices
from string import digits
from collections import Counter #Counter专门用来数数
with open(r'D:\python\LICENSE.txt') as fp:
    content=fp.read()
words=content.split()
print(Counter(words).most_common(10))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值