目 录CONTENT

文章目录

Python练习

简中仙
2023-11-03 / 0 评论 / 0 点赞 / 82 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于2024-02-08,若内容或图片失效,请留言反馈。 本文如有错误或者侵权的地方,欢迎您批评指正!

1、给一个半径,求圆的面积和周长。圆周率3.14

import math    
    
# 从用户获取圆的半径,并将其转换为整数  
radius = int(input('radius = '))    
  
# 计算圆的面积。公式为 pi * r^2  
area = math.pi * radius ** 2    
  
# 打印圆的面积,保留两位小数  
print("area = {:.2f}".format(area))    
  
# 计算圆的周长。公式为 2 * pi * r  
print('circumference =', math.pi * 2 * radius)

2、输入两个数,比较大小后,从小到大升序打印

# 提示用户输入第一个数,并将输入的字符串转换为整数后存储在变量a中  
a = int(input("first="))  
  
# 提示用户输入第二个数,并将输入的字符串转换为整数后存储在变量b中  
b = int(input("second="))  
  
# 使用if语句来比较a和b的大小  
if a > b:  
    # 如果a大于b,则打印b和a,这里使用print函数打印两个数,  
    # 并用逗号分隔,打印出来的形式会是"b,a",其中b是较小的数,a是较大的数  
    print(b, a)  
else:  
    # 如果a不大于b(即a小于等于b),则打印a和b,打印出来的形式会是"a,b",  
    # 其中a是较小的数,b是较大的数或者两者相等  
    print(a, b)

或者

# 获取用户输入并转换为整数,存储在变量a中  
a = int(input('请输入第一个整数: '))    
  
# 获取用户输入并转换为整数,存储在变量b中  
b = int(input('请输入第二个整数: '))  
  
# 使用条件表达式来比较a和b的大小,并打印结果  
# 如果a大于b,则打印 b, a,否则打印 a, b  
print(b, a) if a > b else print(a, b)

3、依次输入若干个整数,打印出最大值。如果输入为空,则退出程序

# 请求用户输入一个数字作为初始最大值,并将输入转换为整数类型存储在变量m中  
m = int(input('Input your first number:'))  
  
# 开始一个无限循环,以便持续接收用户的输入  
while True:  
    # 提示用户输入一个数字,并将输入存储在变量c中  
    c = input('Input a number:')  
      
    # 检查用户是否输入了数字  
    if c:  
        # 将输入转换为整数类型,并存储在变量n中  
        n = int(c)  
          
        # 判断用户输入的数字n是否大于当前的最大值m  
        if n > m:  
            # 如果n大于m,则更新最大值m为n  
            m = n  
          
        # 打印当前的最大值m  
        print('Max is', m)  
    else:  
        # 如果用户没有输入任何内容(直接按回车),则打印"Exit."并退出循环  
        print('Exit.')  
        break

4、给定一个不超过5位的正整数(不转换为字符串),判断该数的位数,依次打印出万位、千位、百位、十位、个位的数字

难点在于如何对一个正整数进行迭代处理(暂不考虑使用字符串
假设有数字54321,目标打印出5、4、3、2、1。

第一循环 54321 // 10000 =5 54321 % 10000 =5

第二循环 4321 // 1000 =4 4321 % 1000 =4

第三循环 321 // 100 =3 321 % 100 =3

第四循环 32 // 10 =2 32 % 10 =2

第五循环 1 // 1 =1 1 % 1 =1

每一次循环中,整除就能获得最高位置的数,取模就能获得出去最高位的数的剩余数字,且取模后的数字作为下一趟的待处理数字。

# 假设c是一个不超过5位的整数  
c = int('54321')  # 不超过5位数  
  
# 定义一个权重w,初始值为10000,用于从右至左提取每一位数字  
w = 10000
  
# 循环5次,因为c最多有5位  
for i in range(5):  
    # 通过整数除法(//),我们得到c除以w的商,这实际上是提取了c的最高位数字  
    x = c // w
      
    # 使用模运算(%),我们得到c除以w的余数,这是去除了最高位数字后的新c  
    c = c % w
      
    # 打印提取的数字  
    print(x)
      
    # 将权重w除以10,以便在下一次迭代中提取下一个数字  
    w //= 10

或者

# 将字符串'54321'转换为整数并赋值给c,这里的c不会超过5位数  
c = int('54321')  # 不超过5位数  
  
# 定义一个权重w,初始值为10000,用于从c中提取每一位数字  
w = 10000  
  
# 循环5次,以提取c的每一位数字  
for i in range(5):  # 计算第四次后,余数就是个位数  
    # 使用整数除法得到商,即c的当前最高位数字,并赋值给x  
    x = c // w  
      
    # 使用模运算得到余数,即去除了当前最高位数字后的新c  
    c = c % w  
      
    # 打印提取的数字x  
    print(x)  
      
    # 将权重w除以10,以便在下一次迭代中提取下一个数字  
    w //= 10  
else:  
    # 循环结束后,打印c的余数,如果c是5位数,则余数为0,否则余数为c的最低位数字  
    print(c)  # 余数

或者

# 将字符串'54321'转化为整数,并赋值给c。此处假设c不超过5位数  
c = int('54321') 
  
# 设置一个权重为10000,用于从c中提取每一位数字  
w = 10000
  
# 假设数字长度为5,用于记录最终提取出来的非零数字的长度  
length = 5
  
# 初始化一个标记flag为False,用于判断是否找到了第一个非零数字  
flag = False
  
# 循环5次,用于提取c中的每一位数字  
for i in range(5):  
    # 通过整数除法提取c的最高位数字,并赋值给x  
    x = c // w  
      
    # 如果还没有找到第一个非零数字  
    if not flag:
        # 如果x非零,说明找到了第一个非零数字  
        if x:
            flag = True # 打标记,表示已经找到第一个非零数字  
        else:  
            length -= 1 # 如果x为0,则在找到第一个非零数字前遇到了零,减少length的值  
      
    # 如果已经找到了第一个非零数字,则打印x  
    if flag:  
        print(x)  
      
    # 通过模运算去掉c的最高位数字,用于下一次循环提取下一个数字  
    c = c % w  
      
    # 将权重w除以10,用于下一次循环提取下一个数字  
    w //= 10  
  
# 打印最终提取出来的数字的长度  
print('The length of the number is', length)

5、输入n个数,求每次输入后的算数平均数

# 初始化变量s用于存储输入数字的和  
s = 0  # 和  
# 初始化变量n用于存储输入数字的次数  
n = 0  # 次数  
  
# 无限循环,等待用户输入  
while True:  
    # 接收用户输入,并存储在变量i中  
    i = input('>>')  
      
    # 判断用户输入是否为'quit',如果是,则退出循环  
    if i == 'quit':  
        break  
      
    # 用户输入不是'quit',则输入次数n加1  
    n += 1  
      
    # 将用户输入转换为整数,并累加到s中  
    s += int(i)  
      
    # 计算当前平均值  
    avg = s / n  
      
    # 打印当前平均值  
    print(avg)

6、打印一个边长为n的空心正方形

# 设置菱形的大小  
n = 5  
  
# 使用字符'*'来绘制菱形  
char = '*'  
  
# 打印菱形的顶部  
print(char * n)  
  
# 循环用于打印菱形的中间部分  
for i in range(n - 2):  
    # 打印左边的'*'  
    print(char, end='')  
  
    # 打印中间的空格  
    print(' ' * (n - 2), end='')  
  
    # 打印右边的'*'  
    print(char)  
  
# 打印菱形的底部  
print(char * n)

或者

# 设置菱形的大小为5行  
n = 5  
  
# 使用星号作为菱形的字符  
char = '*'  
  
# 循环遍历每一行  
for i in range(n):  
    # 如果是第一行或最后一行  
    if i == 0 or i == n - 1:  
        # 打印n个星号,形成菱形的顶部和底部  
        print(char * n)  
    else:  
        # 打印一个星号,然后打印n-2个空格,再打印一个星号,形成菱形的中间部分  
        print(char + ' ' * (n - 2) + char)

另一种思路

取模,能整除n-1的就打印所有*

n = 5  # 设置菱形的大小  
  
# 循环遍历每一行,这里直接使用了5次循环,也可以替换为使用变量n,即for i in range(n):  
for i in range(5):  
    # 判断当前行号i是否是n-1的倍数(即第一行或最后一行)  
    if i % (n - 1) == 0:  
        # 如果是,则打印n个连续的'*',形成菱形的顶部和底部  
        print('*' * n)  
    else:  
        # 如果不是,则打印一个'*',接着打印n-2个空格,然后再打印一个'*',形成菱形的中间部分  
        print('*' + ' ' * (n - 2) + '*')

7、求100内所有奇数的和(2500)

# 初始化变量s为0,用于存储奇数和  
s = 0  
  
# 使用for循环遍历1到99之间的所有奇数,步长为2  
# 即循环变量i的值依次为1, 3, 5, ..., 97, 99  
for i in range(1, 100, 2):  
    # 将当前奇数i累加到变量s中  
    s += i  
  
# 打印变量s的值,即1到99之间所有奇数的和  
print(s)

建议使用sum内置函数,作用是求和

print(sum(range(1, 100, 2)))

8、成绩问题

判断学生成绩,成绩等级A至E。其中,90分以上为'A',8089分为'B',7079分为'C',60~69分为'D',60分以下为'E'

# 定义一个分数  
score = 88  
  
# 判断分数是否大于等于90  
if score >= 90:  
    # 如果分数大于等于90,打印等级'A'  
    print('A')  
# 判断分数是否大于等于80且小于90  
elif score >= 80:
    # 如果分数在80到90之间(不包括90),打印等级'B'  
    print('B')  
# 判断分数是否大于等于70且小于80  
elif score >= 70:
    # 如果分数在70到80之间(不包括80),打印等级'C'  
    print('C')  
# 判断分数是否大于等于60且小于70  
elif score >= 60:
    # 如果分数在60到70之间(不包括70),打印等级'D'  
    print('D')  
else:  
    # 如果分数小于60,打印等级'E'  
    print('E')

9、求1到5阶乘之和

方法一

# 初始化n为5,代表我们要计算从1到5的每个数的阶乘的和  
n = 5  
  
# 初始化s为0,用于存储阶乘的和  
s = 0  
  
# 外层循环遍历从1到n的每个数  
for i in range(1, n + 1):  
    # 初始化临时变量tmp为1,用于存储当前数的阶乘  
    tmp = 1  
      
    # 内层循环从2遍历到当前数i,计算阶乘  
    for j in range(2, i + 1):  
        # 将j乘到tmp上,逐步计算阶乘  
        tmp *= j  
      
    # 将计算出的阶乘加到s上  
    s += tmp  
      
    # 打印当前数的阶乘  
    print(tmp)  
  
# 打印最终的阶乘和  
print(s)

方法二

# 设置n为5,表示我们要计算从1到5的数的阶乘的和  
n = 5  
  
# 初始化s为0,用于存储阶乘的和  
s = 0  
  
# 初始化tmp为1,用于存储阶乘的临时结果  
tmp = 1  
  
# 循环遍历从1到n的每个数  
for i in range(1, n + 1):  
    # 将tmp乘以当前数i,计算阶乘  
    tmp *= i  
  
    # 将计算得到的阶乘累加到s中  
    s += tmp  
  
# 打印最终的阶乘和s  
print(s)

10、给一个数,判断它是否是素数(质数)

质数:一个大于1的自然数只能被1和它本身整除

方法1

最简单的思路,按照定义来,假设有一个数n(n>1),从2开始判断,一直判断到n-1。

# 设置n为12577,这个数避开了3、5、10、2的倍数,因此可能是一个质数  
n = 12577  
  
# 初始化标志flag为False,我们假定n不是合数,如果n能被某个数整除,则标志置为True  
flag = False  
  
# 开始测试从2到n-1的所有数是否能整除n  
for i in range(2, n):  
    # 如果n能被i整除,说明n是一个合数,将标志flag置为True,并结束循环  
    if n % i == 0:  
        flag = True  
        break  
  
# 根据标志flag的值判断n是质数还是合数,并打印结果  
if flag:  
    print(n, 'is a composite number')  # 如果flag为True,则n是合数  
else:  
    print(n, 'is a prime number')  # 如果flag为False,则n是质数

与2取模,就可以直接判断它是否是一个偶数。

使用else子句

# 设置n为12577,该数字特意避开了3、5、10、2的倍数,以用于示例  
n = 12577  
  
# 通过一个循环从2遍历到n-1来检查n是否为质数  
for i in range(2, n):  
    # 如果n能被i整除,说明n是一个合数  
    if n % i == 0:  
        # 输出结果并说明n是一个合数  
        print(n, 'is a composite number')  
        # 结束循环,因为我们已经确定n是一个合数  
        break  
else:  
    # 如果循环完毕都没有找到能整除n的数,说明n是一个质数  
    print(n, 'is a prime number')

11、打印九九乘法表

思路:

1、使用for循环

# 外层循环,控制行数,从1循环到9(包括9)  
for a in range(1, 10):
    # 内层循环,控制列数,从1循环到当前行数a(包括a)  
    for b in range(1, a + 1):
        # 使用format函数格式化字符串,打印出b*a=b*a的乘法表达式  
        print('{0}*{1}={2}'.format(b, a, b * a), end='\t')  
    # 打印完一行后,换行  
    print()

输出

1*1=1	
1*2=2	2*2=4	
1*3=3	2*3=6	3*3=9	
1*4=4	2*4=8	3*4=12	4*4=16	
1*5=5	2*5=10	3*5=15	4*5=20	5*5=25	
1*6=6	2*6=12	3*6=18	4*6=24	5*6=30	6*6=36	
1*7=7	2*7=14	3*7=21	4*7=28	5*7=35	6*7=42	7*7=49	
1*8=8	2*8=16	3*8=24	4*8=32	5*8=40	6*8=48	7*8=56	8*8=64	
1*9=9	2*9=18	3*9=27	4*9=36	5*9=45	6*9=54	7*9=63	8*9=72	9*9=81

分析:

  • range作用:range(1,10)表示从1到10,range(1,a+1)表示从1到a+1
  • format()函数:用来收集其后的位置参数和关键字段参数,并用他们的值填充字符串中的占位符,'{0}*{1}={2}'.format(b,a,b*a)意思是将b填充到{0},a填充到{1},b*a填充到{2},{0}*{1}={2}也可写为{}*{}={}
  • end='\t':表示换行

扩展

1*1=1	2*1=2	3*1=3	4*1=4	5*1=5	6*1=6	7*1=7	8*1=8	9*1=9	
		2*2=4	3*2=6	4*2=8	5*2=10	6*2=12	7*2=14	8*2=16	9*2=18	
				3*3=9	4*3=12	5*3=15	6*3=18	7*3=21	8*3=24	9*3=27	
						4*4=16	5*4=20	6*4=24	7*4=28	8*4=32	9*4=36	
								5*5=25	6*5=30	7*5=35	8*5=40	9*5=45	
										6*6=36	7*6=42	8*6=48	9*6=54	
												7*7=49	8*7=56	9*7=63	
														8*8=64	9*8=72	
																9*9=81

解答:

# 外层循环,控制行数,从1循环到9(包括9)  
for a in range(1, 10):
    # 打印前置的制表符,用于对齐乘法表。部分控制台可能需要更多的制表符来正确对齐,如print('\t' * 2 * (a - 1), end='')  
    print('\t' * (a - 1), end='') 
  
    # 内层循环,控制列数,从a循环到9(包括9),因此开始为a-0即a  
    for b in range(a - 0, 10):
        # 使用format函数格式化字符串,打印出b*a的乘法表达式  
        print('{0}*{1}={2}'.format(b, a, b * a), end='\t')  
      
    # 打印完一行后,换行  
    print()

2、使用while嵌套

# 初始化行数为1  
row = 1  
  
# 当行数小于等于9时进入循环  
while row <= 9:  
    # 对于每一行,初始化列数为1  
    column = 1  
      
    # 当列数小于等于行数时进入循环  
    while column <= row:  
        # 打印乘法公式,例如:1*1=1,1*2=2,2*2=4等  
        print('{}*{}={}'.format(column, row, row * column), end='\t')  
          
        # 完成一次打印后,列数加1,准备打印下一个乘法公式  
        column += 1  
      
    # 当一行打印完成后,换行  
    print()  
      
    # 准备打印下一行,行数加1  
    row += 1

分析:

  • while嵌套会在使row没有等于9时不断重复运行代码
  • row += 1 和column += 1意思是使变量在代码运行结束时+1

3、列表表达式

L = '\n'.join(
    ['\t'.join(['{}*{}={}'.format(column, row, row * column) for column in range(1, row + 1)]) for row in range(1, 10)])
print(L)
# 说明
# 初始化一个空字符串L,用来存储九九乘法表的结果  
L = ''  
  
# 通过外层循环遍历行,从1到9  
for row in range(1, 10):  
    # 内层循环遍历列,从1到当前行号  
    for column in range(1, row + 1):  
        # 使用format格式化字符串,生成乘法公式,并添加到L中  
        L += '{}*{}={}\t'.format(column, row, row * column)  
    # 每完成一行的乘法公式后,换行  
    L += '\n'  
  
# 打印九九乘法表的结果  
print(L)

12、用户登录验证

  • 用户依次输入用户名和密码,然后提交验证
  • 用户不存在、密码错误,都显示用户名或密码错误提示
  • 错误3次,则退出程序
  • 验证成功则显示登录信息
# 设置用户名和密码  
username = 'tom'  
password = 'tom'  
  
# 初始化登录成功标志为False  
flag = False  
  
# 循环三次尝试登录  
for i in range(3):  
    # 获取用户输入的用户名  
    u = input('请输入用户名:')  
      
    # 获取用户输入的密码  
    p = input('请输入密码:')  
      
    # 检查用户名和密码是否正确  
    if username == u and password == p:  
        # 如果正确,设置登录成功标志为True,并退出循环  
        flag = True  # 成功直接break  
        break  
    else:  
        # 如果不正确,打印错误提示,并给用户两次机会重新输入  
        print('用户名或密码错误,您还有', 2-i, '次尝试机会。')  
  
# 根据登录成功标志,打印相应的提示信息  
if not flag:  
    print('登录失败次数过多,账户已被锁定。')  
else:  
    print('登录成功!')

13、打印下图菱形

   *
  ***
 *****
*******
 *****
  ***
   *

分析

行号星个数前空格数总空格数
1136
2324
3512
4700
5512
6324
7136

方法一:

n = 7  
height = n // 2  # 菱形上半部分的高度  
fill_char = '*'  
  
# 循环遍历菱形的每一行  
for i in range(-height, n - height):  
    # 打印每一行,使用居中格式化  
    print("{:^{}}".format((n - 2 * abs(i)) * fill_char, n))

方法二:

# 遍历从-3到3的范围,包括-3和3  
for i in range(-3, 4):  
    # 根据i的值计算空格的数量。如果i是负数,空格数量为-i,否则为i  
    spaces = -i if i < 0 else i  
    # 使用格式化字符串来创建并打印每一行。每一行包含'spaces'数量的空格,以及7-2*spaces数量的星号  
    print(f' {" " * spaces} * {(7 - 2 * spaces)} ')

方法三:

# 循环从-3到3,包括-3和3(总共7次迭代)  
for i in range(-3, 4):  
    # 计算空格的数量,使用绝对值函数确保空格数为非负数  
    spaces = abs(i)  
    # 计算星号的数量,公式是7减去两倍的空格数,这样可以保证每一行的字符总数为7  
    stars = 7 - 2 * spaces  
    # 使用格式化字符串将空格和星号组合成一行  
    # f-string可以让我们直接把变量嵌入到字符串中,提高代码的可读性  
    line = f' {" " * spaces} {"*" * stars}'  
    # 打印这一行  
    print(line)

居中打印

# 循环从-3到3,总共会执行7次  
for i in range(-3, 4):  
    # 计算当前行需要的星号数量。7减去两倍的i的绝对值,确保总数为7  
    stars_count = 7 - 2 * abs(i)  
    # 使用字符串格式化来居中显示星号。"{:^7}"表示宽度为7并居中对齐  
    # 通过format方法,将计算得到的星号数量转为对应的星号字符串  
    line = "{:^7}".format('*' * stars_count)  
    # 打印该行的内容  
    print(line)

1、打印对顶三角形

*******
 *****
  ***
   *
  ***
 *****
*******

分析

序号对称序列星号数总空格前置空格后置空格
137000
225211
313422
401633
513422
625211
737000

方法一

n = 7  
# 计算菱形上半部分的高度,由于菱形的宽度为n,所以高度为n//2  
e = n // 2  
  
# 循环遍历菱形的每一行  
# range的参数从-e到e,包括了菱形上半部分和下半部分的所有行  
for i in range(-e, e + 1):  
    # 计算当前行左侧的空格数。空格数为e减去当前行的绝对值  
    spaces = e - abs(i)  
    # 计算当前行的星号数。星号数为2乘以当前行的绝对值再加1  
    stars = 2 * abs(i) + 1  
      
    # 打印当前行,由spaces个空格和stars个星号组成  
    print(spaces * ' ' + stars * '*')

方法二

# 设置菱形的最大宽度为7  
n = 7  
  
# 循环从-3到3,这是基于n//2的结果,这样确保了菱形的高度和宽度相适应  
for i in range(-3, 4):  
    # 计算当前行需要的星号数量。2 * abs(i) + 1 是根据菱形的形状来确定的  
    stars_count = 2 * abs(i) + 1  
      
    # 生成由星号组成的字符串。例如,如果stars_count为3,那么结果就是'***'  
    star_string = '*' * stars_count  
      
    # 使用字符串格式化来居中显示星号字符串。"{:^7}"表示宽度为7并居中对齐  
    print("{:^7}".format(star_string))  
      
# 如果不想使用上面的方式来生成星号字符串,也可以使用下面这行代码来代替print语句  
# line = (2 * abs(i) + 1) * '*'  
# print("{:^{}}".format(line, n))

2、打印闪电

   *
  **
 ***
*******
   ***
   **
   *

分析

行号*个数前空格数后空格数总空格数数据
11336-3
22235-2
33134-1
470000
533141
623252
713363

方法一

# 遍历从-3到3的范围  
for i in range(-3, 4):  
    # 如果i小于0(即-3到-1),打印宽度为-i的空格和宽度为4+i的星号  
    if i < 0:  
        print(' ' * (-i) + '*' * (4 + i))  
    # 如果i大于0(即1到3),打印宽度为3的空格和宽度为4-i的星号  
    elif i > 0:  
        print(' ' * 3 + '*' * (4 - i))  
    # 如果i等于0,即菱形的中间行,打印宽度为7的星号  
    else:  
        print('*' * 7)

方法二

# 设置菱形的最大宽度为 7  
n = 7  
  
# 计算菱形上半部分的高度,因为菱形是对称的,所以高度是最大宽度的一半  
e = n // 2  
  
# 计算菱形下半部分的高度(包括中间行),f 为 e+1,因为下半部分比上半部分多一行  
f = e + 1  
  
# 循环遍历菱形的每一行,i 的范围是从 -e 到 f(不包括 f)  
for i in range(-e, f):  
    # 如果 i 小于 0,表示在菱形的上半部分  
    if i < 0:  
        # 打印当前行,前面是 -i 个空格,后面是 (f + i) 个星号  
        print(' ' * -i + (f + i) * '*')  
    # 如果 i 大于 0,表示在菱形的下半部分(不包括中间行)  
    elif i > 0:  
        # 打印当前行,前面是 e 个空格,后面是 (f - i) 个星号  
        print(' ' * e + (f - i) * '*')  
    # 如果 i 等于 0,表示在菱形的中间行  
    else:  # 这个 else 条件可以简写为 `elif i == 0:`,但为了清晰明确,我们保持这样写也没有问题  
        # 打印中间行,这一行全是星号,数量为 n  
        print(n * '*')

14、打印100以内的斐波那契数列

斐波那契数列指的是这样一个数列:

0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711……

如果设F(n)为该数列的第n项(n∈N*),那么这句话可以写成如下形式::F(n)=F(n-1)+F(n-2)F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2),这是一个线性递推数列

它的规律是:这个数列从第 3 项开始,每一项都等于前两项之和。

思路

1、for循环

# 初始化变量 i 和 j,它们是斐波那契数列的前两个数字  
i = 1  
j = 0  
  
# 创建一个范围从0到100的循环,用于生成斐波那契数列  
for a in range(101):  
    # 计算斐波那契数列的下一个数字,即前两个数字的和  
    number = i + j
      
    # 在进入下一次循环之前,更新i和j的值  
    i = j
    j = number
      
    # 如果生成的斐波那契数字超过100,就退出循环  
    if number > 100:
        break  
    else:  # 否则,打印生成的斐波那契数字  
        print(number)

2、while循环

# 初始化斐波那契数列的前两个数字  
a = 0  
b = 1  
  
# 打印斐波那契数列的第一个数字  
print(a)
  
# 使用无限循环开始生成斐波那契数列  
while True:  
    # 打印斐波那契数列的第二个及以后的数字  
    print(b)
      
    # 计算下一个斐波那契数  
    c = a + b
      
    # 如果生成的斐波那契数超过100,则跳出循环  
    if c > 100: break
      
    # 更新斐波那契数列的前两个数字,以备下一次循环使用  
    a = b  
    b = c

15、求斐波那契数列第101项

方法一

# 初始化斐波那契数列的前两个数字,第一个数为1,第二个数为0  
a = 1    
b = 0
  
# 打印第一个数(即索引为0的数)  
print('index={},fib={}'.format(0, b))
  
# 打印第二个数(即索引为1的数)  
print('index={},fib={}'.format(1, a))
  
# 初始化索引为2,用于记录当前生成的数的位置  
index = 2    
  
# 使用无限循环开始生成并打印斐波那契数列  
while True:    
    # 计算下一个斐波那契数,即前两个数的和  
    c = a + b    
      
    # 更新索引值  
    index += 1    
      
    # 打印当前生成的斐波那契数及其索引位置  
    print('index={},fib={}'.format(index, c))    
      
    # 如果生成的数的索引达到102,则跳出循环。注意:这里用102是为了打印到索引为101的数  
    if index == 102: break  
      
    # 更新斐波那契数列的下一个两个数,以备下一次循环使用  
    a = b    
    b = c

方法二

# 初始化斐波那契数列的前两个数字,都为1  
a = 1  
b = 1  
  
# 通过for循环来计算斐波那契数列  
# 注意这里循环了101次,所以计算的是第101个斐波那契数  
for count in range(101):  
    # 这一行是斐波那契数列的核心计算逻辑  
    # 它实现了这样的计算: b = a + b, a = b  
    # 即在下一次循环中,a和b会分别变为前一次循环中的b和a+b  
    a, b = b, a + b  
# for-else结构中的else部分会在for循环正常结束后执行  
# 这里就是在循环结束后打印出第100个斐波那契数  
else:  
    print(b)

方法三

# 初始化斐波那契数列的前两个数  
a = 1    
b = 1    
    
# 循环从第三个数开始计算到第102个数  
for i in range(2, 102):    
    # 如果当前是第101个数  
    if i == 101:    
        # 打印第101个斐波那契数  
        print(b)    
    else:    
        # 计算下一个斐波那契数,并更新a和b的值  
        a, b = b, a + b

16、求10万内的所有素数

方法一

# 设置要查找素数的上限  
num = 100000  
  
# 初始化一个空字符串,用于存储所有的素数  
strs = ''  
  
# 遍历2到num-1的所有数字  
for i in range(2, num):  
    # 遍历2到i的平方根的所有数字,检查是否有能整除i的因子  
    for c in range(2, int(i ** 0.5) + 1):  
        if i % c == 0:  
            # 如果找到了能整除i的因子,则跳出内部循环,继续下一个数字的检查  
            break  
    else:  
        # 如果没有找到能整除i的因子,说明i是一个素数,将其添加到字符串中  
        strs += str(i) + ' '  
  
# 打印所有的素数  
print(strs)

方法二

# 初始化计数器,用于统计找到的素数数量  
count = 0  
  
# 外层循环从2遍历到99999,检查每一个数字是否为素数  
for a in range(2, 100000):  
    # 内层循环从2遍历到a的平方根,试图找到a的因子  
    for b in range(2, int(a ** 0.5) + 1):  
        # 如果找到了a的一个因子(即a能被b整除),则跳出内层循环  
        if a % b == 0:  
            break  
    else:  
        # 如果内层循环完成,没有找到a的因子,那么a就是一个素数  
        # 打印出这个素数,并且计数器加1  
        print(a)  
        count += 1  
  
# 打印出找到的素数数量  
print("Total prime numbers found:", count)

方法三

# 初始化计数器为1,因为我们已经知道2是素数,所以从3开始计数  
count = 1  
  
# 从3开始,以步长为2遍历到99999,这样只检查奇数  
for a in range(3, 100000, 2):  
      
    # 假设a是素数,我们将在内部循环中检查这个假设  
    is_prime = True  
      
    # 从3开始,以步长为2遍历到a的平方根,只检查奇数可能的因子  
    for b in range(3, int(a ** 0.5) + 1, 2):  
          
        # 如果a能被b整除,那么a不是素数  
        if a % b == 0:  
            is_prime = False  
            break  
              
    # 如果a是素数,打印它的值  
    if is_prime:  
        print(a)  
        count += 1  
  
# 打印出找到的素数数量  
print("Total odd prime numbers found:", count)

查看程序运行时间

import datetime
start = datetime.datetime.now()
# 程序
delta = (datetime.datetime.now() - start).total_seconds()  # 它不是精确的CPU,它是墙上的时间
print(count, delta)

17、求100内的素数

  • 从2开始到自身的数-1中找到一个能整除的=>从2开始到自身开平方的数中找到一个能整除的
  • 一个合数一定可以分解成几个素数的乘积,也就是说,一个数如果能被一个素数整除就是合数

方法一

import datetime    
  
# 获取当前时间,用于后续计算程序运行时间    
start = datetime.datetime.now()
  
# 设置一个上限,用于遍历所有的数字    
n = 100000
  
# 2和3都是质数,所以初始化质数的数量为2    
count = 2
  
# 从3开始遍历所有的奇数,步长为2(只考虑奇数,因为偶数除了2以外不可能是质数)    
for x in range(3, n, 2):
    # 假设x是质数  
    is_prime = True  
      
    # 遍历所有奇数因子,步长为2,只考虑到x的平方根即可(如果x不是质数,那么它必然有一个因子不大于它的平方根)    
    for i in range(3, int(x ** 0.5) + 1, 2):
        # 如果x能被i整除,说明x不是质数    
        if x % i == 0:    
            # x不是质数,标记并结束内层循环    
            is_prime = False  
            break    
              
    # 如果内层循环结束后,x仍然是质数,则质数计数器+1    
    if is_prime:    
        count += 1   
          
# 计算程序运行时间    
delta = (datetime.datetime.now() - start).total_seconds()
  
# 打印找到的质数的数量和程序运行的时间    
print("Total prime numbers found:", count)  
print("Program run time in seconds:", delta)

方法二

import datetime  
  
start = datetime.datetime.now()  # 记录开始时间  
  
n = 100000  # 设置搜索上限  
  
count = 2  # 初始化质数计数器为2,因为2和3是前两个质数  
  
primenumbers = [3]  # 初始化质数列表,从3开始(为什么是3?因为2是唯一的偶数质数,而我们的循环从5开始,只考虑奇数,所以从3开始)  
  
# 循环遍历从5开始的奇数  
for x in range(5, n, 2):  # 从5开始,步长为2,舍弃掉所有偶数,因为除了2以外,偶数都不是质数  
  
    edge = int(x ** 0.5)  # 计算x的平方根并向下取整,用作判断x是否为质数的一个界限  
  
    flag = False  # 初始化标志位为False,表示x目前未被认定为质数  
  
    # 遍历质数列表中的每一个质数  
    for i in primenumbers:  
        if i > edge:  # 如果当前质数i大于界限edge,说明x是质数  
            flag = True  # 设置标志位为True  
            break  # 退出循环,因为已经确定x是质数  
        if x % i == 0:  # 如果x能被当前质数i整除,说明x不是质数,而是合数  
            break  # 退出循环,因为已经确定x不是质数  
  
    if flag:  # 如果标志位为True,说明x是质数  
        count += 1  # 质数计数器加1  
        primenumbers.append(x)  # 将新的质数x添加到质数列表中  
  
delta = (datetime.datetime.now() - start).total_seconds()  # 计算程序运行时间  
  
print(count, delta)  # 打印找到的质数的数量和程序运行时间

经过测试发现,上面的代码计算效率最高。算法中增加了列表,记录了质数,控制了边界后,使用质数来取模比使用奇数计算更少。空间换时间,使用列表空间存储质数列表,来换取计算时间。

1、孪生素数性质

大于3的素数只有6N-1和6N+1两种形式,如果6N-1和6N+1都是素数称为孪生素数

方法一

import datetime  
  
# 记录程序开始时间  
start = datetime.datetime.now()    
  
# 设置需要检测的最大数字  
n = 100000  
  
# 从7开始检测,因为2,3,5已经被确定为质数  
x = 7  
  
# 设置步长,初始为4,用于在x的基础上递增得到下一个待检测的数字  
step = 4    
  
# 已知的质数列表,初始包含2,3,5三个质数  
primenumbers = [3, 5]    
  
# 记录找到的质数个数,初始为3,因为2,3,5是质数  
count = 3    
  
# 当x小于n时,进行循环检测  
while x < n:  
    # 如果x不是5的倍数,才可能是质数,才需要进行下一步的检测  
    if x % 5 != 0:  
        # 计算x的平方根并向下取整,用于减少质数检测次数  
        edge = int(x ** 0.5)  
        # 标志位,用于标记x是否为质数,初始为False  
        flag = False  
        # 在已知的质数列表中进行检测  
        for i in primenumbers:  
            # 如果i大于edge,说明x是质数,因为x的所有可能因子都已经检测过  
            if i > edge:  
                flag = True  # 标记x为质数  
                break        # 跳出循环  
            # 如果x能被i整除,说明x是合数  
            if x % i == 0:  
                break  # 跳出循环  
        # 如果x被标记为质数,则增加质数个数,并将x加入到质数列表中  
        if flag:  
            count += 1  
            primenumbers.append(x)  
    # 步长变换,如果是2就变为4,如果是4就变为2,这样可以跳过偶数(除了2以外的偶数不可能是质数)  
    x += step  
    step = 4 if step == 2 else 2  
  
# 计算程序运行时间  
delta = (datetime.datetime.now() - start).total_seconds()  
  
# 打印找到的质数个数和程序运行时间  
print(count, delta)

方法二

import datetime  
  
start = datetime.datetime.now()  # 记录程序开始时间  
n = 100000  
count = 2  # 从3开始,所以初始质数数量为2(2和3)  
primenumbers = [2, 3]  # 质数列表,从2开始  
for x in range(5, n, 2):  # 从5开始,步长为2,只测试大于2的奇数   
    if x % 5 == 0:  # 如果x能被5整除,那就不是质数  
        continue  # 跳过本次循环,进入下一次循环  
    edge = int(x ** 0.5)  # 计算x的平方根并向下取整,用于减少需要检查的除数数量  
    flag = False  # 标志位,假设x是质数  
    for i in primenumbers:  # 遍历已知的质数列表  
        if i > edge:  # 如果已知的质数i大于x的平方根,那么x不可能是合数,因为合数必定有一个因子小于等于其平方根  
            flag = True  # 设置标志位为True,表示x是质数  
            break  # 退出循环,不再检查其他的质数  
        if x % i == 0:  # 如果x能被已知的质数i整除,那么x就是合数  
            break  # 退出循环,不再检查其他的质数  
    if flag:  # 如果标志位为True,表示x是质数  
        count += 1  # 质数计数器加1  
        primenumbers.append(x)  # 将新的质数加入到质数列表中  
  
delta = (datetime.datetime.now() - start).total_seconds()  # 计算程序运行时间  
print(count, delta)  # 打印找到的质数数量和程序运行时间

18、计算杨辉三角前6行

  • 第n行有n项,n是正整数52
  • 第n行数字之和为2**(n-1)
  • 打印出杨辉三角的每一行数字即可

img

img

解法一:逐行计算

# 初始化pre为Pascal三角形的第一行  
pre = [1]  
  
# 设置要生成的Pascal三角形的行数  
n = 6  
  
# 循环遍历每一行  
for i in range(n):  
    # 初始化当前行cur,第一个元素总是1  
    cur = [1]  
      
    # 如果不是第一行(因为第一行只有一个元素,就是1)  
    if i != 0:  
        # 遍历前i-1个元素,因为它们可以通过前一行的相邻两个元素相加得到  
        for j in range(1, i):  
            # 当前元素是前一行的相邻两个元素之和  
            cur.append(pre[j - 1] + pre[j])  
          
        # 每行的最后一个元素总是1  
        cur.append(1)  
  
    # 打印当前行  
    print(cur)  
      
    # 将当前行设为下一行的前置行  
    pre = cur

解法一:补零

# 初始化pre为第一行[1],因为Pascal三角形的第一行只有一个元素1  
pre = [1]  # 第一行是特例,因为0+0不等于1  
  
# n表示要生成的Pascal三角形的行数  
n = 6  
  
# 从第二行开始循环生成n-1行Pascal三角形(因为第一行已经初始化给pre了)  
for i in range(1, n):  
    # 在循环内部开辟内存空间,初始化当前行为全0列表  
    cur = [0] * (i + 1)  # 在循环内部开辟内存空间  
  
    # j循环控制当前行的索引  
    for j in range(i + 1):  
        # 如果j是0(即当前行的第一个元素)或j等于i(即当前行的最后一个元素)  
        if j == 0 or j == i:  
            # 当前行的第一个和最后一个元素设为1  
            cur[j] = 1  
        else:  
            # 当前行的元素等于前一行的相邻两个元素之和  
            cur[j] = pre[j - 1] + pre[j]  
  
    # 打印当前行  
    print(cur)  
      
    # 将当前行设为下一行的前一行  
    pre = cur

解法三:对称

  • 杨辉三角中心对称
  • 行索引为奇数,左右数字个数相同,只需计算左边所有数字
  • 行索引为偶数,只需计算左边所有数字,最中心数字只需计算一次
  • 为每一行直接开辟够空间,两端1不要计算了
n = 6  # n表示要生成的杨辉三角的行数  
pre = [1]  # pre存储前一行的值,初始化为[1]  
  
# 循环生成n行Pascal三角形  
for i in range(n):    
    cur = [1] * (i + 1)  # cur存储当前行的值,每行初始化为1  
      
    # j的范围从1到i-1,因为每行的两端都是1,不需要计算  
    for j in range(1, i):    
        cur[j] = pre[j - 1] + pre[j]  # 当前行的每个元素是前一行的相邻两个元素之和  
  
    print(cur)  # 打印当前行  
    pre = cur  # 将当前行设为下一行的前一行

19、依次接收用户输入的3个数,排序后打印

  1. 转换int后,判断大小排序。使用分支结构完成
  2. 使用max函数
  3. 使用列表的sort方法
  4. 冒泡法
  5. sorted()函数

假定默认升序输出

第一种方法

a = []
# while 循环
# while True:
#    a.append(int(input('>>>')))
#    if len(a) >= 3:
#        break
# for 循环
for i in range(3):	# range(1,4) 也可以
    a.append(int(input('请输入数字:')))  # 将输入转换为整数
print(a)

if a[0] > a[1] > a[2]:
    print(a[2], a[1], a[0])
elif a[0] > a[2] > a[1]:
    print(a[1], a[2], a[0])
elif a[1] > a[0] > a[2]:
    print(a[2], a[0], a[1])
elif a[1] > a[2] > a[0]:
    print(a[0], a[2], a[1])
elif a[2] > a[0] > a[1]:
    print(a[1], a[0], a[2])
else:
    print(a[0], a[1], a[2])

第二种方法

# 初始化两个空列表a和b
a = []
b = []
# 从用户那里获取三个数字输入,并将它们添加到列表a中
for i in range(3):
    a.append(int(input('请输入数字:')))  # 将用户输入转换为整数
print(a)

while a:  # 当 a 为空列表
    m = max(a)  # 找到列表 a 中的最大值m
    b.insert(0, m)  # 将这个最大值m插入到列表b的开头
    a.remove(m)  # 从列表a中移除这个最大值m,直到列表a为空
print(b)

第三种方法

a = []
for i in range(3):
    a.append(int(input('请输入数字:')))  # 将输入转换为整数  
print(a)
a.sort()    # 对这个列表进行排序
print(a)

第四种方法

冒泡排序(Bubble Sort)

是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

  • 排序算法,一般都实现为就地排序,输出为升序
  • 扩大有序区,减小无序区。
  • 每一趟比较中,将无序区中所有元素依次两两比较,升序排序将大数调整到两数中的右侧
  • 每一趟比较完成,都会把这一趟的最大数推倒当前无序区的最右侧
import random  
  
# 使用random.sample()直接生成10个不重复的随机数  
a = random.sample(range(1, 101), 10)  
print("原始随机数组:", a)  
  
# 使用冒泡排序对数组进行排序  
for j in range(len(a)):  	# 这是外层循环,它的次数等于数组 a 的长度。每一次循环,都会将当前最大的数“冒泡”到它应该在的位置上
    for k in range(len(a) - j - 1):  	# 这是内层循环。它遍历数组,与相邻的元素进行比较。由于每次外层循环后,最大的数都会冒泡到最后,所以内层循环每次可以减少一次比较
        if a[k] > a[k + 1]:  	# 这个条件判断当前元素 a[k] 是否大于它的下一个元素 a[k + 1]。如果大于,那么它们的顺序是错误的,需要交换
            a[k], a[k + 1] = a[k + 1], a[k]  # 使用Python的元组交换法  
  
print("使用冒泡排序后的数组:", a)
  • 冒泡法需要数据一趟趟比较
  • 可以设定一个标记判断此轮是否有数据交换发生,如果没有发生交换,可以结束排序,如果发生交换,继续下一轮排序
  • 最差的排序情况是,初始顺序与目标顺序完全相反,遍历次数1,..,n-1之和n(n-1)/2
  • 最好的排序情况是,初始顺序与目标顺序完全相同,遍历次数n-1
  • 时间复杂度O(n^2)

第五种方法

import random  
  
# 使用random.sample()直接生成10个不重复的随机数  
a = random.sample(range(1, 101), 10)  
print("原始随机数组:", a)  
  
# 使用sorted()函数对数组进行排序  
a = sorted(a)  
print("排序后的数组:", a)

20、判断数字并打印

用户输入一个十进制正整数数字

1、判断是几位数

2、打印每一位数字及其重复的次数

3、依次打印每一位数字,顺序个、十、百、干、万...位

# 初始化一个空字符串  
num = ''  
  
# 通过循环判断输入,确保输入的是一个正整数  
# 数字输入的简单判断  
while True:  
    num = input('Input a positive number>>>').strip().lstrip('0')  
    if num.isdigit():  
        break  
  
# 打印输入的数字以及其长度  
print("The length of {} is {}.".format(num, len(num)))  
  
# 倒序打印数字方法一:通过range函数倒序遍历索引  
# 倒序打印1  
for i in range(len(num), 0, -1):  
    print(num[i - 1], end='')  
print()  
  
# 倒序打印数字方法二:通过reversed函数倒序遍历字符  
# 倒序打印2  
for i in reversed(num):  
    print(i, end='')  
print()  
  
# 下面的倒序打印方法都是重复的,可以选择删除以提高代码简洁性  
  
# 判断0-9每个数字在输入的数字中出现的次数  
# 初始化一个长度为10的计数器列表  
counter = [0] * 10  
  
# 方法一:通过count函数计算每个数字的出现次数,此方法效率较低,每次count都是全字符串扫描  
for i in range(10):  # 10*n  
    counter[i] = num.count(str(i))  
if any(counter):  # 如果counter中有非0元素,打印计数结果  
    for i in range(10):  
        if counter[i]:  
            print("The count of {} is {}".format(i, counter[i]))  
  
# 方法二:通过遍历每个字符,然后计数,此方法效率较高,只需一次遍历  
counter = [0] * 10  
for x in num:  # 0(n)  
    counter[int(x)] += 1  
if any(counter):  # 如果counter中有非0元素,打印计数结果  
    for i in range(10):  
        if counter[i]:  
            print("The count of {} is {}".format(i, counter[i]))

21、判断数字位数并排序打印

输入5个十进制正整数数字,判断输入的这些数字分别是几位数,将这些数字排序打印,要求升序打印

# 创建一个空列表用于存储用户输入的数字  
nums = []

# 循环直到列表中有5个数字  
while len(nums) < 5:
    # 获取用户输入,去掉前后的空白,并去掉前导0  
    num = input("Please input a number:").strip().lstrip('0')

    # 判断用户输入的是否为数字,如果不是则重新获取输入  
    if not num.isdigit():
        continue

        # 打印输入的数字及其长度  
    print('The length of {} is {}'.format(num, len(num)))

    # 将数字添加到列表中,这里将字符串转换为整数  
    nums.append(int(num))

# 打印最后得到的数字列表  
print(nums)

# 创建一个数字的副本,用于排序  
lst = nums.copy()

# 使用sort()方法对列表进行排序,这将直接修改原列表  
lst.sort()  # 就地修改  
print(lst)

# 使用冒泡排序对原数字列表进行排序  
for i in range(len(nums)):
    flag = False
    for j in range(len(nums) - i - 1):
        # 如果当前数字大于下一个数字,则交换它们的位置  
        if nums[j] > nums[j + 1]:
            tmp = nums[j]
            nums[j] = nums[j + 1]
            nums[j + 1] = tmp
            flag = True
            # 如果在某次循环中没有发生任何交换,那么列表已经排序完成,可以提前退出循环  
    if not flag:
        break

    # 打印排序后的数字列表  
print(nums)

22、解决猴子吃桃问题

猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想吃时,只剩下一个桃子了。求第一天共摘多少个桃子?

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

23、求杨辉三角第n行第k列的值

img

算法一

一次开辟本次列表需要的内存空间,提高效率

只保留2个列表,减少空间使用

# 初始化变量m,表示我们要生成的斐波那契数列的长度  
m = 9  
  
# 初始化变量k,表示我们要获取的斐波那契数列的索引(从1开始)  
k = 5  
  
# 初始化变量pre,它是一个列表,用来存储生成的斐波那契数列。初始化为None,因为还没有生成任何数。  
pre = None  
  
# 开始一个外循环,用来生成斐波那契数列的每一行。我们将生成m行,每行有i+1个元素。  
for i in range(m):  
    # 创建一个新的列表row,用来存储当前正在生成的行。这个列表的长度是i+1,因为我们要生成i+1个元素。  
    row = [1] * (i + 1)  
  
    # 开始一个内循环,用来计算这一行的除了第一个元素之外的其他元素。这些元素都是前两个元素的和。  
    for j in range(1, i):  
        # 计算当前元素的值,它等于前一个元素和前两个元素的和。  
        row[j] = pre[j - 1] + pre[j]  
      
    # 在计算完这一行的所有元素后,将这个行赋值给pre,以便在下一个迭代中生成下一行。  
    pre = row  
  
# 打印一个分隔线,以便在输出中更清楚地看到每一行。  
print('---------')  
  
# 打印最后一行,也就是我们生成的斐波那契数列。由于我们是从0开始索引的,所以第k个元素实际上是这一行的第k-1个元素。  
print(row)	# [1, 8, 28, 56, 70, 56, 28, 8, 1]  
  
# 打印第k个元素的值。注意这里我们使用的是k-1作为索引,因为Python的列表索引是从0开始的。  
print(row[k - 1])	# 70

也可以使用对称,减少迭代次数和计算次数。

算法二

根据杨辉三角的定理:第n行的m个数(m>0且n>0)可表示为C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数。

组合数公式:有m个不同元素,任意取n(n≤m)个元素,记作c(m,n),组合数公式为:

C(m,n)=m!/(n!(m-n)!)
C(m,n)=C(m,m-n)

# 第n行的m个数可表示为C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数  
m = 9  # 定义m为9  
k = 5  # 定义k为5  
  
# C(m-1,k-1),还可等价为C(m-1,m-1-(k-1))=>C(m-1,m-k)  
# 计算组合数C(m-1,k-1),它与C(m-1,m-k)是等价的  
  
# C(n,r)=n!/(r!(n-r)!)  
n = m - 1  # n等于m减1  
r = k - 1  # r等于k减1  
d = n - r  # 计算n-r的值,存储在d中  
  
targets = []  # 创建一个空列表用于存储目标值  
                   # 目标值为 r , n-r , n  
factorial = 1  # 初始化阶乘值为1  
  
# 可以加入k为1或者m的判断,直接返回1  
# 通过循环计算阶乘,当i等于r、d或n时,将阶乘值添加到targets列表中  
for i in range(1, n + 1):  
    factorial *= i  # 计算i的阶乘  
    if i == r:  # 如果i等于r  
        targets.append(factorial)  # 将阶乘值添加到目标列表中  
    if i == d:  # 如果i等于d  
        targets.append(factorial)  # 将阶乘值添加到目标列表中  
    if i == n:  # 如果i等于n  
        targets.append(factorial)  # 将阶乘值添加到目标列表中  
  
print(targets)  # 打印目标列表  
print(targets[2] // (targets[0] * targets[1]))  # 打印最终结果,即C(n,r)的值

i==r、i==n、i==d这三个条件不要写在一起,因为它们有可能两两相等。

算法说明:一趟到n的阶乘算出所有阶乘值。

24、数字统计

随机产生10个数字

要求:

  • 每个数字取值范围[1,20]
  • 统计重复的数字有几个?分别是什么?
  • 统计不重复的数字有几个?分别是什么?
  • 举例:11,7,5,11,6,7,4,其中2个数字7和11重复了,3个数字4、5、6没有重复过

思路:

对于一个排序的序列,相等的数字会挨在一起。但是如果先排序,还是要花时间,能否不排序解决?例如11,7,5,11,6,7,4,先拿出11,依次从第二个数字开始比较,发现11就把对应索引标记,这样一趟比较就知道11是否重复,哪些地方重复。第二趟使用7和其后数字依次比较,发现7就标记,当遇到以前比较过的11的位置的时候,其索引已经被标记为1,直接跳过。

# 导入random模块,用于生成随机数  
import random  
  
# 创建一个空列表nums,用于存储随机生成的数字  
nums = []  
# 在循环中生成10个随机数并添加到nums中  
for _ in range(10):  
    # random.randrange(21)生成一个0到20之间的随机整数,包括0和20  
    nums.append(random.randrange(21))  
# 这行代码注释掉了nums的输出,如果需要查看生成的随机数,可以去掉注释  
# nums=[2,10,19,20,4,17,4,20,11,3]  
print("Origin numbers = {}".format(nums))  
print()  
  
# 获取nums的长度  
length = len(nums)  
# 创建一个空列表samenums,用于存储重复的数字  
samenums = []
# 创建一个空列表diffnums,用于存储不重复的数字  
diffnums = []
# 创建一个长度为length的列表states,用于记录每个数字是否已经出现过,0表示未出现,1表示已出现  
states = [0] * length
  
# 遍历每个数字  
for i in range(length):  
    # 假定当前数字没有重复  
    flag = False
    # 如果当前数字已经出现过,则跳过该数字的后续比较,因为已经确定它是重复的  
    if states[i] == 1:  
        continue  
    # 从i+1开始寻找与当前数字相同的数字,因为i之前的数字已经被考虑过了  
    for j in range(i + 1, length):  
        # 如果j位置的数字已经出现过,则跳过该数字的比较,因为已经确定它是重复的  
        if states[j] == 1:  
            continue  
        # 如果找到了与当前数字相同的数字,则设置flag为True,并把j位置的数字标记为已出现,以便后续不再考虑它  
        if nums[i] == nums[j]:  
            flag = True  
            states[j] = 1  
    # 根据flag的值,判断当前数字是否重复,如果重复,则把该数字添加到samenums中,并把该数字标记为已出现;否则,把该数字添加到diffnums中。  
    if flag:
        samenums.append(nums[i])  
        states[i] = 1  
    else:  
        diffnums.append(nums[i])  
print("Same numbers ={1}, Counter ={0}".format(len(samenums), samenums))  
print("Different numbers ={1}, Counter ={0}".format(len(diffnums), diffnums))

想知道某个数字重复的次数

# 导入random模块,用于生成随机数  
import random  
  
# 创建一个空列表nums,用于存储随机生成的数字  
nums = []  
# 生成10个随机数并添加到nums中  
for _ in range(10):  
    nums.append(random.randrange(21))  
# 手动设置nums的值  
nums = [1, 22, 33, 56, 56, 22, 4, 56, 9, 56, 2, 1]  
print("Origin numbers = {}".format(nums))  
print()  
  
# 获取nums的长度  
length = len(nums)  
# 创建一个空列表samenums,用于存储重复的数字,每个元素是一个元组,元组的第一个元素是重复的数字,第二个元素是该数字出现的次数  
samenums = []
# 创建一个空列表diffnums,用于存储不重复的数字  
diffnums = []
# 创建一个长度为length的列表states,用于记录每个数字是否已经出现过,0表示未出现,非0表示已出现次数(数字本身)  
states = [0] * length  # 记录不同的索引异同状态  
  
# 遍历每个数字  
for i in range(length):  
    # 如果当前数字已经出现过,则跳过该数字的后续比较,因为已经确定它是重复的  
    if states[i] != 0:  
        continue  
    # count用于记录当前数字出现的次数,初始值为0  
    count = 0  # 假定没有重复  
    # 从i+1开始寻找与当前数字相同的数字,因为i之前的数字已经被考虑过了  
    for j in range(i + 1, length):  
        # 如果j位置的数字已经出现过,则跳过该数字的比较,因为已经确定它是重复的  
        if states[j] != 0:  
            continue  
        # 如果找到了与当前数字相同的数字,则把count加1,并把j位置的数字标记为已出现,以便后续不再考虑它  
        if nums[i] == nums[j]:  
            count += 1  
            states[j] = count  
    # 如果count不为0,说明存在重复的数字,把states[i]的值设置为count+1,并把元组(nums[i], states[i])添加到samenums中;否则,把nums[i]添加到diffnums中。  
    if count:  # 有重复  
        states[i] = count + 1  
        samenums.append((nums[i], states[i]))  
    else:  
        diffnums.append(nums[i])  
print("Same numbers={1}, Counter={0}".format(len(samenums), samenums))  # 打印重复数字的数量和列表  
print("Different numbers={1}, Counter={0}".format(len(diffnums), diffnums))  # 打印不同数字的数量和列表  
print(states)  # 打印每个数字的出现次数状态列表

25、集合

  • 共同好友
    • 你的好友A、B、C,他的好友C、B、D,求共同好友
# 定义了一个名为yours的集合,包含元素'B', 'C', 'A'  
yours = {'B', 'C', 'A'}  
  
# 定义了一个名为his的集合,包含元素'B', 'C', 'D'  
his = {'B', 'C', 'D'}  
  
# 使用&运算符找到yours和his的交集,并将结果赋值给变量intersection  
intersection = yours & his  
  
# 打印intersection集合,即yours和his的交集  
print(intersection)
  • 微信群提醒
    • XXX与群里其他人都不是微信朋友关系

已知微信群里有a、b、c三个人,加入了x,x和其他人都不是好友

  • 并集处理

    • x-userid not in(A|B|C|..)==True,X用户的ID并不在该群当前所有成员的好友并集,说明它不是任何人的朋友。这种方式会产生巨大的并集

    • 假设x用户的好友列表是T,该群所有用户的id集合为IDs,IDs&T==set()

# 定义三个集合,分别表示群里三个用户的微信朋友关系  
A = {"userid1", "userid2", "userid3"}  
B = {"userid4", "userid5", "userid6"}  
C = {"userid7", "userid8", "userid9"}  
# 新加入的用户x的微信用户ID  
x_userid = "userid10"  

# 检查x_userid是否在A、B或C中的任意一个中
x_userid in A or x_userid in B or x_userid in C
# 检查x_userid是否在A、B或C集合中  
x_userid in (A | B | C)

# 或者合并三个集合  
IDs = A | B | C
# 检查x_userid是否与集合IDs有交集,如果有交集,则返回True,否则返回False
IDs & x_userid != set()
# 检查删除x_userid后,IDs是否仍然是IDs的子集。如果是,则返回True,否则返回False
IDs - x_userid < IDs
# 使用isdisjoint方法检查x_userid是否与IDs完全独立,即没有任何交集。如果存在交集,则返回False,否则返回True
IDs.isdisjoint(x_userid) == False
  • 有一个API,要求权限同时具备A、B、C才能访问,用户权限是B、C、D,判断用户是否能够访问该API

    • 假设API权限为集合T,用户权限为集合P

      • T&P==T

      • T<=P即T是P的子集

      • T-P==set()差集为空说明P完全包含T

T = {A, B, C}  
P = {B, C, D}  

# 判断T中的所有元素是否都在P中存在,如果都在,那么T就是P的子集,用户可以访问这个API
T - P == set()
# 判断T和P的交集是否等于T。如果等于,说明用户拥有的权限能够满足API的要求,可以访问这个API
T & P == T
# 判断T是否是P的子集。如果是,说明用户的权限集合P包含了API所需的所有权限,用户可以访问这个API
T <= P
# 使用issubset方法判断P是否是T的子集, 这个方法用于检查一个集合(set)是否包含另一个集合(set)中的所有元素的函数
T.issubset(P)
  • 有一个API,要求权限具备A、B、C任意一项就可访问,用户权限是B、C、D,判断用户是否能够访问该API
T = {A, B, C}  
P = {B, C, D}  

# 判断T和P的交集是否不等于空集。如果不等于空集,说明用户拥有的权限能够满足API的要求,可以访问这个API
T & P !== set()
# 判断T中不包含P的元素是否还是T的子集。如果是,说明用户的权限集合P包含了API所需的所有权限,用户可以访问这个API
T - P < T
# isdisjoint方法是判断两个集合是否互不交叠,即没有任何交集。如果isdisjoint返回False,说明两个集合有交集
T.isdisjoint(P) == False
  • 一个总任务列表,存储所有任务。一个已完成的任务列表。找出为未完成的任务

    • 任务ID不重复

    • 所有任务ID集合放到集合ALL中

    • 所有已经完成的任务ID都放到集合COMPLETED中,它一定是ALL的子集

    • ALL-COMPLETED=>UNCOMPLETED

列表运算

# 总任务列表,包含所有任务  
ALL = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  
print("总任务列表:", ALL)  
  
# 已完成任务列表,包含已完成任务的ID  
COMPLETED = [2, 4, 6, 8, 10]  
print("已完成任务列表:", COMPLETED)  
  
# 定义一个空列表,用于存储未完成的任务ID  
UNCOMPLETED = []  
  
# 遍历总任务列表中的每一个任务ID  
for id in ALL:  
    # 检查当前的任务ID是否在已完成任务列表中  
    if id not in COMPLETED:  
        # 如果当前任务ID不在已完成任务列表中,就把它添加到UNCOMPLETED列表中  
        UNCOMPLETED.append(id)  
print("未完成任务列表:", UNCOMPLETED)

或者集合运算(推荐)

# 定义一个总任务列表,存储所有的任务,这里使用数字1到10作为示例任务  
ALL = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}  
  
# 打印总任务列表,用于核对和确认总任务列表的内容  
print(ALL)  
  
# 定义一个已完成的任务列表,这里使用数字2, 4, 6, 8, 10作为已完成的任务示例  
COMPLETED = {2, 4, 6, 8, 10}  
  
# 使用集合操作“-”从总任务列表中移除已完成的任务,得到未完成的任务列表  
# 这是一种快捷的方法来找到两个列表的差集  
UNCOMPLETED = ALL - COMPLETED  
  
# 打印未完成的任务列表,这些就是需要继续完成的任务  
print(UNCOMPLETED)
  • 随机产生2组各10个数字的列表,如下要求:
    • 每个数字取值范围[10,20]
    • 统计20个数字中,一共有多少个不同的数字?
    • 2组之间进行比较,不重复的数字有几个?分别是什么?
    • 2组之间进行比较,重复的数字有几个?分别是什么?
    • 例如,两组数分别是[1,9,5,7,4]、[1,5,6,8],两组数一共有7个不同的数字,两组间不同的数字有5个,两组间重复的数字有2个
import random

g1 = []
g2 = []
# 生成两组随机数字  
for i in range(10):
    g1.append(random.randint(10, 20))
    g2.append(random.randint(10, 20))
print(g1, g2, sep='\n')
# 使用集合(set)统计每组中不同的数字数量  
# set()函数会去除列表中的重复元素,返回一个包含不重复元素的集合
s1 = set(g1)
s2 = set(g2)
# 使用集合的并集操作符(|)统计两组中不同的数字数量
print(s1 | s2)
# 使用集合的交集操作符(&)统计两组中相同的数字数量
print(s1 & s2)
# 使用集合的对称差集操作符(^)统计两组中的不同和重复的数字数量
print(s1 ^ s2)

26、用户输入一个数字

打印每一位数字及其重复的次数

# 获取用户输入的数字字符串,去除前后的空白字符和正负号  
num = input('>>>').strip().lstrip('0+-')  
print(type(num), num)  # 打印输入数字的类型和内容  
  
# 创建一个空字典,用于存储每个数字出现的次数  
d = {}  
  
# 遍历输入的数字字符串中的每个字符  
for c in num:  
    # 如果字符不在字典的键中(即还未出现过),则将其添加到字典中并设置值为1  
    if c not in d.keys():  
        d[c] = 1  
    # 如果字符已经在字典的键中(即已经出现过),则将其值增加1  
    else:  
        d[c] += 1  
print(d)  # 打印每个数字出现的次数  
  
# 创建另一个空字典,使用setdefault方法来统计每个数字出现的次数  
d = {}  
for c in num:  
    d[c] = d.setdefault(c, 0) + 1  
print(d)  # 打印每个数字出现的次数,与方法1的结果相同  
  
# 创建第三个空字典,使用get方法来统计每个数字出现的次数  
d = {}  
for c in num:  
    d[c] = d.get(c, 0) + 1  
print(d)  # 打印每个数字出现的次数,与方法1的结果相同  
  
# 创建第四个空字典,使用collections中的defaultdict来统计每个数字出现的次数  
from collections import defaultdict  
d = defaultdict(lambda: 0)  # 使用默认值为0的字典来存储结果  
for c in num:  
    d[c] += 1  
print(d)  # 打印每个数字出现的次数,与方法1的结果相同

27、数字重复统计

  • 随机产生100个整数
  • 数字的范围[-1000,1000]
  • 升序输出这些数字并打印其重复的次数
# 导入random模块,该模块包含用于生成随机数的函数  
import random  
  
# 定义一个变量n,表示我们要生成的随机整数的数量,这里设置为100  
n = 100  
  
# 定义一个长度为n的列表nums,并初始化所有元素为None  
nums = [None] * n  
  
# 使用for循环来生成n个随机整数。range(n)产生一个从0到n-1的整数序列,我们在每个位置上生成一个随机数。  
for i in range(n):  
    # random.randint(a, b)生成一个在[a, b]范围内的随机整数,包括a和b。  
    nums[i] = random.randint(-1000, 1000)  
  
# 打印生成的随机数列表  
print(nums)  
  
# 定义一个字典counter,用于统计每个数字出现的次数  
counter = {}  
  
# 再次使用for循环来统计每个数字出现的次数  
for x in nums:  
    # counter.get(x, 0)尝试获取字典中x键的值,如果x键不存在,则返回默认值0,然后在这个值上加1。  
    counter[x] = counter.get(x, 0) + 1  
  
# 使用sorted函数和counter字典的items方法来得到一个升序的元素和它们出现次数的列表,然后打印这个列表。  
print(sorted(counter.items()))

28、字符串重复统计

  • 字符表abcdefghijklmnopqrstuvwxyz
  • 随机挑选2个字母组成字符串,共挑选100个
  • 降序输出所有不同的字符串及重复的次数
# 导入Python的string模块,该模块包含了一些有用的字符串函数
import random
import string

# 创建一个字符表,包含小写字母a-z  
alphabet = string.ascii_lowercase
# 打印字符表  
print(alphabet)

# 另一种创建字符表的方式,范围是97-122(ASCII值),这是因为我们需要的是小写字母a-z  
alphabet = bytes(range(97, 123)).decode()
# 打印字符表  
print(alphabet)

# 创建并打印字符表"abcdefghijklmnopqrstuvwxyz"  
alphabet = "abcdefghijklmnopqrstuvwxyz"
print(alphabet)

# 创建一个空列表,用于存储随机生成的字符串  
words = []
# 在循环中,生成100个由两个随机字母组成的字符串,并添加到列表words中  
for i in range(100):
    # 两种随机选择字母的方式都可以,random.choices和random.sample都可以从列表中随机选择元素  
    # words.append(random.choice(alphabet)+random.choice(alphabet))  
    words.append("".join(random.choices(alphabet, k=2)))
    # words.append("".join(random.sample(alphabet, k=2)))  
print(words)

# 创建一个空字典,用于存储每个字符串及其出现的次数  
d = {}
# 在循环中,遍历列表words,统计每个字符串出现的次数,并存储到字典d中  
for word in words:
    d[word] = d.get(word, 0) + 1
print(sorted(d.items(), reverse=True))

29、封装解构练习

  • 从nums = [1, (2, 3, 4), 5]中,提取其中4出来
_, (*_, num), _ = [1, (2, 3, 4), 5]
print(num)

(_, [*_, num], _) = [1, (2, 3, 45), 5]
print(num)
  • 从list(range(10))中,提取第二个、第四个、倒数第二个元素
_, a, _, b, *_, c, _ = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a, b, c)
  • 环境变量JAVA_HOME=/usr/bin,返回环境变量名和路径
name, sep, path = "JAVA_HOME=/usr/bin".partition('=')
print(name, path)
0

评论区