python基础练习

打印一个边长为n的正方形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
n = 5    # 设置打印边长的星号数
print('*'*n) # 打印第一行
for i in ('*'*(n-2)): # 设置循环为减去上下两条边的数量
print('*'+' '*(n-2)+'*')
# 先打印前面一个星号,再打印减去了前后两个星号的空格,最后打印最后一个星号
print('*'*n) # 打印最下面一行的*

n = 6
e = -n//2
for i in range(e,n+e):
if i == e or i == n+e-1:
print('*'*n) # 上面判断的是要打印上下两条边
else:
print('*' + ' '*(n-2) + '*')

# 上面的代码等价于下面的代码
n = 5
for i in range(n):
if i == 0 or i == n-1:
print('*'*n)
else:
print('*'+' '*(n-2)+'*')

求100以内所有奇数的和

1
2
3
4
sum = 0
for i in range(1,100,2):
sum += i
print(sum)

求1到5的阶乘之和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 方法1
n = 5 # 控制阶乘的边界
sum = 0
for i in range(1,n+1):
tmp = 1 # 第一次1的阶乘还是1
for j in range(1,i+1):
tmp *= j # 第一次1的阶乘是1×1
sum += tmp # 第一次sum=0+1
print(sum)
# 1+1*2+1*2*3+1*2*3*4+1*2*3*4*5

# 方法2
nums = 1
sum = 0
for n in range(1,6):
nums *= n
# 这里是乘等,第一次是1×1,第二次是1×1×2,第三次是1×1×2×3,这样就实现了阶乘,再使用下面的方法将每次循环的结果加在一起就形成了阶乘之和。
sum += nums
print(sum)

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

1
2
3
r=int(input('r='))
print('area='+str(3.14*r*r))
print('circumference='+str(2*3.14*r))

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

1
2
3
4
5
6
7
8
9
a = input('first: ')
b = input('second: ')
if a > b:
print(b, a)
else:
print(a, b)

# 三元表达式
print(b,a) if a>b else print(a,b)

获取最大值

1
2
3
4
5
6
7
8
9
10
11
12
# 请输入若干个整数,打印出最大值
m = int(input('Input first number >>>'))
while True:
c = input('Input a number >>>')
if c:
n = int(c)
if n > m:
m = n
print('Max is', m)
else:
break
# m是保存最大值的,c保存每次输入的数字并传给n,用n和m比较。这实际还是在做两个数的比较

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

1
2
3
4
5
6
7
8
9
10
n = 0    # 次数
sum = 0 # 和
while True:
i = input('>>>')
if i == 'quit':
break
n += 1
sum += int(i)
avg = sum/n
print(avg)

打印九九乘法表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
for i in range(1,10):
for j in range(1,10):
print("%d*%d=%2d" % (i,j,i*j),end=" ")
print("")
1*1= 1 1*2= 2 1*3= 3 1*4= 4 1*5= 5 1*6= 6 1*7= 7 1*8= 8 1*9= 9
2*1= 2 2*2= 4 2*3= 6 2*4= 8 2*5=10 2*6=12 2*7=14 2*8=16 2*9=18
3*1= 3 3*2= 6 3*3= 9 3*4=12 3*5=15 3*6=18 3*7=21 3*8=24 3*9=27
4*1= 4 4*2= 8 4*3=12 4*4=16 4*5=20 4*6=24 4*7=28 4*8=32 4*9=36
5*1= 5 5*2=10 5*3=15 5*4=20 5*5=25 5*6=30 5*7=35 5*8=40 5*9=45
6*1= 6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 6*7=42 6*8=48 6*9=54
7*1= 7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 7*8=56 7*9=63
8*1= 8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 8*9=72
9*1= 9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
# 这种方法没有考虑到边界的问题

方法一:
for i in range(1,10):
for j in range(1,10):
if j <= i:
print(j,"*",i,"=",i*j,end=" ")
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

方法二:
for i in range(1,10):
for j in range(i,10):
print('{}x{}={}\t'.format(i, j, i*j), end=' ')
# print(str(i)+'*'+str(j)+'='+str(i*j),end=' ')
# print(i,'*',j,'=',i*j,end=' ')
# 上面这样打印也可以,只是很难看
print("")
# 最后一行打印的是一个换行符
1 * 1 = 1 1 * 2 = 2 1 * 3 = 3 1 * 4 = 4 1 * 5 = 5 1 * 6 = 6 1 * 7 = 7 1 * 8 = 8 1 * 9 = 9
2 * 2 = 4 2 * 3 = 6 2 * 4 = 8 2 * 5 = 10 2 * 6 = 12 2 * 7 = 14 2 * 8 = 16 2 * 9 = 18
3 * 3 = 9 3 * 4 = 12 3 * 5 = 15 3 * 6 = 18 3 * 7 = 21 3 * 8 = 24 3 * 9 = 27
4 * 4 = 16 4 * 5 = 20 4 * 6 = 24 4 * 7 = 28 4 * 8 = 32 4 * 9 = 36
5 * 5 = 25 5 * 6 = 30 5 * 7 = 35 5 * 8 = 40 5 * 9 = 45
6 * 6 = 36 6 * 7 = 42 6 * 8 = 48 6 * 9 = 54
7 * 7 = 49 7 * 8 = 56 7 * 9 = 63
8 * 8 = 64 8 * 9 = 72
9 * 9 = 81

方法三:
for i in range(1,10):
for k in range(1,i):
print(end="\t ")
# 这行就是为了打印前面的空行的,这里需要一个Tab键加一个空格键才能让输出对齐
for j in range(i,10):
print('{}x{}={}\t'.format(i, j, i*j), end=' ')
print("")
1x1=1 1x2=2 1x3=3 1x4=4 1x5=5 1x6=6 1x7=7 1x8=8 1x9=9
2x2=4 2x3=6 2x4=8 2x5=10 2x6=12 2x7=14 2x8=16 2x9=18
3x3=9 3x4=12 3x5=15 3x6=18 3x7=21 3x8=24 3x9=27
4x4=16 4x5=20 4x6=24 4x7=28 4x8=32 4x9=36
5x5=25 5x6=30 5x7=35 5x8=40 5x9=45
6x6=36 6x7=42 6x8=48 6x9=54
7x7=49 7x8=56 7x9=63
8x8=64 8x9=72
9x9=81
# 实际输出要更整齐一些


方法四:
for i in range(1,10):
for k in range(1,10-i):
print(end="\t ") # 打印每一行前面的Tab键,第一行就要打印9个
for j in range(1,i+1):
print("{}*{}={}".format(i,j,i*j), end="\t ")
# \t放在end=""中好像更容易理解
print("")

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

方法五:
for i in range(1,10):
for j in range(1,i+1):
print('{}*{}={}'.format(i,j,i*j), end="")
# 这种把算式打印在前面,之后再加分隔符的方法中,分隔符使用什么都可以,可以是空格或Tab键或什么也不加
print()
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81

打印100以内的斐波那契数列及打印第101项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 费波那契数列由0和1开始,之后的费波那契系数就是由之前的两数相加而得出。首几个费波那契系数是:
# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233……(OEIS中的数列A000045)
# 特别指出:0不是第一项,而是第零项。

# 打印100以内的斐波那契数
a=0
b=1
print(a)
print(b)
for i in range(1,100):
c = a + b
if c > 100:
break
print(c)
a=b
b=c
# 如果小于100就打印,大于100就停止。

# 打印101项斐波那契数
a = 0
b = 1
# 手动打印前两项
print('{},{}'.format(0, a))
print('{},{}'.format(1, b))
index = 1
while True:
c = a + b
a = b
b = c
index += 1
print('{},{}'.format(index, c))
# 这里的index就是显示中前面的序号
if index == 101:
break

# 只打印第101项
a=0
b=1
#print(a)
#print(b)
for i in range(1,101):
c = a + b
a=b
b=c
if i < 100:
continue
print(c)
# 打印一定要放在最后,因为如果放在c = a + b下方,那么就无法将if判断加入进去了

a = 0
b = 1
# print('{},{}'.format(0,a))
# print('{},{}'.format(1,b))
index = 1
while True:
c = a + b
a,b = b,c
index += 1
if index == 101:
print('{},{}'.format(index,c))
break

求素数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
方法1
# 最简单的思路,按照定义来,假设有一个数n(n>1),从2开始判断,一直判断到n-1
n = 12577 # 避开3、5、10、2的倍数
flag = False
for i in range(2,n):
if n % i == 0: # 找到条件是什么
flag = True
print(i) # 这里打印的是可以整除的数字
break
if flag:
print(n, 'is not a prime number. ')
else:
print(n, 'is a prime number. ')

方法2
n = 1577 # 避开3、5、10、2的倍数
# 对这个数从2开始测试到n-1
for i in range(2,n):
if n % i == 0: # 找到条件是什么
print(n, 'is not a prime number. ')
break
else:
print(n, 'is a prime number')

求10万内的所有素数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 质数(Prime number),又称素数,指在大于1的自然数中,除了1和该数自身外,无法被其他自然数整除的数(也可定义为只有1与该数本身两个正因数的数)。
# 大于1的自然数若不是素数,则称之为合数(也称为合成数)。
# 算术基本定理确立了素数于数论里的核心地位:任何大于1的整数均可被表示成一串唯一素数之乘积。
# 为了确保该定理的唯一性,1被定义为不是素数,因为在因式分解中可以有任意多个1(如3、1×3、1×1×3等都是3的有效约数分解)。
import time
t = [2] # 素数是从2开始的
t0 = time.time()
count = 1
# 去掉所有偶数,从3开始迭代,步进为2
for x in range(3,100001,2):
if x > 5 and x % 10 == 5:
# 所有大于10的质数中,个位数只有1、3、7、9,大于5且以5结尾的整数都能被5整除,这里首先过滤掉大于5且以5结尾的整数
continue
for i in range(3, int(x ** 0.5) + 1, 2):
# 这里的int最后加1,是因为前包后不包,所以要加1. 这一步就是为了测试当前的数字是否可以被i这个数字整除。
# 比如这时x是49,那么就要测试49是否可以被从3开始,到49开平方后加1的数字,并且去除了偶数,也就是剩下的这些数字整除,如果不能就是素数。
# 这一步是想表达,如果一个整数可以被其平方根因子前面的数整除就一定可以被平方根因子后面的数整除,所以只算平方根因子前面的数就可以了。
# 一个整数的前后对应的两个因子的乘积等于这个整数,所以一个整数如果平方根之前有一个因子,那平方根之后肯定有一个对应的因子,中间是平方根
# 上面所说的“一个整数的前后对应的两个因子的乘积等于这个整数”,是想表示如2*50=100,100就是那个整个,2就是前面的因子,50是后面的因子
# 平方根就在这两个因子之间。
if x % i == 0:
break
else:
count += 1
t.append(x)
# 这个else是for语句的,当x可以整除i时,就跳出循环,否则就在count中加一个计数,并将x回到t列表中
print(t)
print('花费时间: {}'.format(time.time() - t0))
print('质数个数: {}'.format(count))
print('质数个数: {}'.format(len(t)))

# 讲解:
for i in range(2, 100):
if not 100 % i: # 如果100与i取余不为1,那么就打印
print(i)

# 100 = 2 x 50
# 100 = 4 x 25
# 100 = 5 x 20
# 100 = 10 x 10
# 这样很容易看出,在平方根10之前,如果100有一个因子,那么平方根后面一定有一个对应的因子,而平方根`10x10`是临界点。
# 所以被除数可以从平方根处砍掉后面的部分。
# 上面的意思是想说明,2*50=100和50*2=100是一个意思,所以在平方根上面的因子计算完就可以了,可以忽略掉平方根下面的因子
# 由于相差一个指数,一个整数的平方根通常都比自身小很多,数值越大,相差越大。
# 比如100比10大90,10000比100大9900,这样看就发现数据量减少了不止一星半点。

打印菱形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 思路:
# 行号 个数 前空格 总空格数
# 1 1 3 6
# 2 3 2 4
# 3 5 1 2
# 4 7 0 0
# 5 5 1 2
# 6 3 2 4
# 7 1 3 6
# 这是中心对称的
# 我们关注的是一行如果打满星号总共的数量与前空格一列,每行菱形前面的空格从3-0,再从0-3
for i in range(-3,4):
if i < 0:
prespace = -i
# 这里是将数字变为正数
else:
prespace = i
print(' '*prespace+'*'*(7-prespace*2))
# 这是发现的公式。' '*prespace是要打印的空格数,'*'*(7-prespace*2))是要打印几个星号。

# 三目运算符方法
for i in range(-3,4):
prespace=-i if i < 0 else i
# 这里不能写成prespace=-i if (i < 0) else prespace=i,这样会报语法错误。
print(' '*prespace+'*'*(7-prespace*2))

打印对顶三角形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 思路:
# 行号 对称序列 星号数 总空格数 前置空格数 后置空格数
# 1 3 7 0 0 0
# 2 2 5 2 1 1
# 3 1 3 4 2 2
# 4 0 1 6 3 3
# 5 1 3 4 2 2
# 6 2 5 2 1 1
# 7 3 7 0 0 0
# 可以看出,只与前置空格、起点、终点有关
n = 7
e = n//2 # 因为是对称问题所以除2?
for i in range(-e, n-e):
prespace = -i if i<0 else i # 这一步是将数字都变为正数
print(' '*(e-prespace) + '*'*(2*prespace+1))

打印闪电

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 思路:
# 行号 个数 前空格 后空格数 总空格数 数据
# 1 1 3 3 6 -3
# 2 2 2 3 5 -2
# 3 3 1 3 4 -1
# 4 7 0 0 0 0
# 5 3 3 1 4 1
# 6 2 3 2 5 2
# 7 1 3 3 6 3
# 看一下上面数据一列
方法1
for i in range(-3,4):
if i < 0:
print(' '*(-i)+'*'*(4+i))
elif i > 0:
print(' '*3+'*'*(4-i))
else:
print('*'*7)

方法2
j = '*'
for i in range(-3,4):
if i == 0:
print(j*7)
print(" "*(-i) + j*(i+4)) if i<0 else print(3*" " + j*(3-i))

解决猴子吃桃问题

1
2
3
4
5
6
7
8
9
# 猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到了第10天早上想吃时,只剩下一个桃子了。求第一天共摘了多少个桃子。
# 猴子应该第九天吃完时就已经知道只剩下一个桃子了。
n=1 # 这是最后剩下的桃子的数目
for _ in range(1,10):
# 如果是一个不关心或没用的变量可以使用下划线代替,这个变量在这里只是为了迭代使用的。
n=(n+1)*2
print(n)
# 从题目中得出公式:x/2-1=n,x是桃子的总数,n是剩下桃子的数目,反过来就得到(n+1)*2就是总的桃子的数目。将这个公式迭代9次就是总的数目。
# 所以用range(1,10)

杨辉三角

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
-----------
方法一
-----------
triangle=[[1],[1,1]]
for i in range(2,6):
# 从2开始是因为前两个列表已经有了,所以从2开始
cur = [1]
# 这是每个元素的第一个1
pre = triangle[i-1]
# 这里定义的pre是要计算的列表元素的上一个元素,也就是triangle列表中的哪个小的列表。如第一次要计算的就是
# 第三个元素,所以pre就是第二个。说明pre等于triangle列表中的第几个列表,如i等于1,那么,pre就等于
# triangle[0],因为这是triangle中的第一个列表。当第一次i等于2时这里是[1,1]
for j in range(len(pre)-1):
# len(pre)是计算pre这个列表中有几个元素。这个循环就是在凑前后两个1中间的部分。第一次循环时,len(pre)的
# 结果是2,减去1后j等于0。这里这样做是因为在杨辉三角中每行的行号与这一行中元素的个数是一样的。如第三行
# 的列表中就有三个元素,这里减1是因为上面的cur已经定义了每个元素的第一个1,最后的1还没追加,所以减去1
# 就是两个1中间的元素的个数了
cur.append(pre[j]+pre[j+1])
# pre[j]+pre[j+1]第一次计算的结果是2,也就是pre[0]+pre[0+1],这时的pre等于[1,1],所以pre的第0个
# 和第1个元素都是1,所以相加得2。之后将pre[2]追加到了cur中,cur这时是[1],所以结果就是[1,2]。再加上
# 下面追加的1,就成了第三个元素[1,2,1]
cur.append(1)
# 这是向cur的一个列表中插入1,如原来是[1],插入后就是[1,1],这插入的应该是每个元素最后一个1。上面的循环
# 结束到这一步,也就意味着一个元素计算完毕,下面追加到triangle列表中,之后就可以进入下个循环了。
triangle.append(cur)
# 这里再将cur追加到现在的triangle中,就有了[[1], [1, 1], [1, 2, 1]]
print(triangle)
# 输出结果:[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1]]

# 方法一变体
triangle=[]
n = 4
for i in range(n):
row = [1]
# 这是每一个元素的第一个1
triangle.append(row)
# 追加row到triangle列表中
if i == 0:
continue
for j in range(i-1):
# 当i是2的时候会进入这个循环,计算两个1中间的部分,这里j是0
row.append(triangle[i-1][j]+triangle[i-1][j+1])
# triangle[i-1][j]中的[i-1]表示triangle中的第几个小列表,之后的[j]表示列表中的第几个元素。如果
# i是2的话,那么triangle[i-1]就是triangle中的第1个小列表,也就是[1,1],这时j等于0,
# triangle[i-1][j]的结果就是1,triangle[i-1][j+1]的结果也是1,但它们表示[1,1]中前后两个不同的1,
# 再将它们相加就是2,这就算出了两个1中间的部分。当i等于3时,这里会循环两次,所以能算出两个3
row.append(1)
# 这是每个元素的最后一个1
print(triangle)
# 输出结果:[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1]]

======================================================================================
triangle = []
row = [1]
triangle.append(row)
row.append(1)
row.append(999)
print(triangle)
# 发现这样的问题,虽然按顺序执行会先将row插入到triangle中,但之后再向row中插入一个1和999,这时triangle
# 不会是[[1]],而是[[1,1,999]]。可以向列表中的元素列表中直接添加子元素
======================================================================================

-------------------
方法二-while
-------------------
n = 6
oldline = []
# oldline就是为了凑每行的[1]和1之后的部分
newline = [1]
# length = 0
print(newline)
# 先打印出第一行的[1]
for i in range(1,n):
# 这里会循环1-5
oldline = newline.copy()
# 这是浅拷贝。先把每行的第一个1凑出来。第二次循环时,这里的oldline就会复制成了[1,1],因为newline变了
oldline.append(0)
# 尾部加0,这时的oldline是[1,0],向oldline中追加0是为了下面计算各元素的值
newline.clear()
# 清空newline,这时的newline是[]
offset = 0
while offset <= i: # 满足条件进入循环,这里计算的是从第二行开始的数据
newline.append(oldline[offset - 1] + oldline[offset])
# 这里开始凑每行中的所有内容,第一次i是1,offset是0,oldline[0-1] + oldline[0],这时oldline[-1]
# 是0,oldline[0]是1,这两个数相加也就是[1],把[1]追加到newline中,下面offset自增加1,因为offset
# 和i都是1,所以还会进一次循环,newline现在是[1],oldline[1-1] + oldline[1],这时oldline[0]是1,oldline[1]是0,这两个数相加也是[1],追加到newline这个列表中,这时newline是[1,1]。之后offset
# 再增加1,这时offset大于i,退出循环。最后就打印出了第二行的[1,1]
offset += 1
print(newline)

----------------
方法二-for
----------------
n = 6
oldline = []
newline = [1]
# length = 0
print(newline)
for i in range(1,n):
oldline = newline.copy()
# 这是浅拷贝
oldline.append(0)
# 尾部加0,相当于两端加0
newline.clear()
offset = 0
for j in range(i+1):
newline.append(oldline[j-1]+oldline[j])
print(newline)
# 这个方法与上面的while方面的思路是一样的。

======================================================================================
# 如何比较两段代码的效率?效率一是看时间,一是看进入循环的次数
# 算10以内的质数-1
import datetime
# 要装载这个模块
n = 100000
pn = []
count = 0
# 这是为了计数。用count计算进入循环的次数
start = datetime.datetime.now()
# 设置一个开始时间

for x in range(2,n):
for i in pn:
# 通过这样的方式,向pn列表中添加元素。第一次pn是空,2会被添加到pn中。之后随着pn的增长,x会与pn中所
# 有的数字进行取余,如果结果是0就跳出与pn列表中数字取余的循环。否则,这个与pn列表中数字取余的数字x
# 就是质数
count += 1
if x % i == 0:
break
else:
pn.append(x)
#print(pn)
delta = (datetime.datetime.now() - start).total_seconds()
# 用现在的时间减去开始时间,.total_seconds计算全部时间差。
print(len(pn))
print(count)
print(delta)

# 算质数-2
import datetime
import math
n = 100000
pn = []
flag = False
count = 0
start = datetime.datetime.now()
for x in range(2,n):
for i in pn:
count += 1
if x % i == 0:
# 这是如果进来了,就不是质数。实际与2、3、5等取余为0的都会在这个条件下被屏蔽掉。
flag = True
break
if i >= math.ceil(x**0.5):
# 这里如果进来了,就是质数。ceil() 函数返回数字的上入整数。x**0.5就是对x开方。到这里的都是筛选过一
# 次的数字了
flag = False
break
# 先用x与i取余,如果是0,就表示不是质数。如果结果都不为0,再用
if not flag:
pn.append(x)
# print(pn)
delta = (datetime.datetime.now() - start).total_seconds()
print(len(pn))
# 计算打印的个数
print(count)
print(delta)
======================================================================================

------------
方法三
------------
# 尾部追加效率最高
# 能不能一次性开辟空间。所谓一次性开辟,就是将一列先算出来,不断向后追加,直到追加完最后一个1。中间部分先用数字填充,下面两例使用0或1来填充。如[1,0,1] [1,1,1,1]
# 列表解析式
# 循环迭代
# 能不能少算一半的数字
# 思路:先开辟新列表,把列表中元素的个数先定下来,之后再改。下面计算包括中间点向左部分的数字,
# 也就是range(1,i//2+1),之后每计算出中间点向左部分的数字时,都会用if判断语句在反方向相对应的位置加入
# 相同的一个数字。最后修改的是中间部分的数字。
triangle = []
n = 6
for i in range(n):
# 这里的循环从0-5
row = [1]
# 开始的1
for k in range(i):
# 当i是0的时候,不会执行for k in循环下面的语句,因为k是空。
row.append(1) if k == i-1 else row.append(0)
# 如果k等于i-1,那么就向row后追加1,否则就追加0。上面这条语句是在中间填0,尾部填1
triangle.append(row)
# 第一次因为i是0,所以直接到这里,将row插入到triangle列表中,之后到下面的语句,当i为0时跳出此轮循环,
# 返回到循环的首部。第二次因为i是1,所以执行上面循环的语句,向row中插入1,row变成了[1,1]
if i == 0:
continue
for j in range(1,i//2+1):
# 当i是1时,这里是for j in range(1,1),因为是range(1,1)所以不会向下执行。i=2时,也就是计算到第三行
# 才能进来。这是少算一半数字吗?只算中点以前的数字,然后根据结果追加数字,在中间点的数字前或后,所以这里
# 要除2再加1,因为是前包后不包,所以要加1
# 当i是4时,这里循环两次,j是1时,triangle[3][0] + triangle[3][1],就是[1,3,3,1],可以算出左半边
# 的4,下面把row[1]=4,这时row是[1,4,1,1,1],再向下执行到if语句时,会在反方向对应的位置加入相同的数
# 字,也就成了[1,4,1,4,1],j是2时,triangle[3][1]+triangle[3][2],就是[1,3,3,1]中的3加3,也就
# 是中间的数字6被计算出来了。
val = triangle[i-1][j-1] + triangle[i-1][j]
row[j] = val
if i != 2*j:
# 条件满足,修改中点以后数据的值,从后向前数,偶数行都会满足这里的条件,或者说,每行中前后两个数字能有对
# 称的,都会满足这里的条件,只有计算到奇数的中间点数字时,不能满足这里的条件
row[-j-1] = val
print(triangle)
# 这个方法就是先将一列计算出来,中间部分先用数字填充,最后再一个一个修改中间的数字。

# 方法三变体
triangle = []
n = 6
for i in range(n):
row = [1] * (i+1)
# 一次性开辟
triangle.append(row)
for j in range(1,i//2+1):
# i=2第三行才能进来
val = triangle[i-1][j-1] + triangle[i-1][j]
row[j] = val
if i != 2*j:
# 奇数个数的中间点数字跳过,也就是只有计算偶数行时才会进入这里,因为计算奇数行时,i一定是一个偶数
row[-j-1] = val
print(triangle)
作者

John Doe

发布于

2019-06-20

更新于

2023-03-17

许可协议