Datewhale学习笔记5
$\textcolor{blue}{Datewhale学习笔记}$$\textcolor{red}{chap5}$
聪明办法学 Python 2nd Edition
Chapter 5 循环 Loop
for 循环和循环范围
for 循环的特点
基于提供的范围,重复执行特定次数的操作
In [1]
def sumFromMToN(m, n):
total = 0
# 注意: range(x, y) 是左闭右开区间,包含 x,不包含 y
for x in range(m, n+1):
total += x
return total
In [2]
sumFromMToN(5, 10)
45
In [3]
sumFromMToN(5, 10) == 5+6+7+8+9+10
True
range()
是个什么东西?
其实在这里,我们也可以不用循环来完成同样的任务
In [4]
def sumFromMToN(m, n):
return sum(range(m, n+1))
In [5]
sumFromMToN(5, 10)
45
如果我们省略第一个参数会发生什么?
In [6]
def sumToN(n):
total = 0
# range 起始范围默认为 0
for x in range(n+1):
total += x
return total
In [7]
sumToN(5)
15
那如果我们添加第三个参数呢?
In [8]
def sumEveryKthFromMToN(m, n, k):
total = 0
# 第三个参数为 “步长” step
for x in range(m, n+1, k):
total += x
return total
In [9]
sumEveryKthFromMToN(5, 20, 7) == (5 + 12 + 19)
True
只对从 m
到 n
的 奇数求和
In [10]
# 我们也可以通过修改循环内部的代码来改变步长
def sumOfOddsFromMToN(m, n):
total = 0
for x in range(m, n+1):
if x % 2 == 1:
total += x
return total
In [11]
sumOfOddsFromMToN(4, 10) == sumOfOddsFromMToN(5,9) == (5+7+9)
True
现在我们反着来试一下!
In [12]
# 我们将生成一个反向数字序列
# (仅供演示使用,代码实践中不建议这么做)
def sumOfOddsFromMToN(m, n):
total = 0
for x in range(n, m-1, -1):
if x % 2 == 1:
total += x
return total
In [13]
sumOfOddsFromMToN(4, 10) == sumOfOddsFromMToN(5,9) == (5+7+9)
True
还有更多方法来解决这个问题
for 循环嵌套
In [14]
# 下面的代码将输出二维坐标
def printCoordinates(xMax, yMax):
for x in range(1, xMax+1):
for y in range(1, yMax+1):
print(f"( {x} , {y} ) ", end="")
print()
In [15]
printCoordinates(5, 5)
( 1 , 1 ) ( 1 , 2 ) ( 1 , 3 ) ( 1 , 4 ) ( 1 , 5 )
( 2 , 1 ) ( 2 , 2 ) ( 2 , 3 ) ( 2 , 4 ) ( 2 , 5 )
( 3 , 1 ) ( 3 , 2 ) ( 3 , 3 ) ( 3 , 4 ) ( 3 , 5 )
( 4 , 1 ) ( 4 , 2 ) ( 4 , 3 ) ( 4 , 4 ) ( 4 , 5 )
( 5 , 1 ) ( 5 , 2 ) ( 5 , 3 ) ( 5 , 4 ) ( 5 , 5 )
In [16]
from IPython.display import IFrame
IFrame('https://pythontutor.com/visualize.html#code=%23%20%E4%B8%8B%E9%9D%A2%E7%9A%84%E4%BB%A3%E7%A0%81%E5%B0%86%E8%BE%93%E5%87%BA%E4%BA%8C%E7%BB%B4%E5%9D%90%E6%A0%87%0A%0Adef%20printCoordinates%28xMax,%20yMax%29%3A%0A%20%20%20%20for%20x%20in%20range%281,%20xMax%2B1%29%3A%0A%20%20%20%20%20%20%20%20for%20y%20in%20range%281,%20yMax%2B1%29%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print%28f%22%28%20%7Bx%7D%20,%20%7By%7D%20%29%20%20%22,%20end%3D%22%22%29%0A%20%20%20%20%20%20%20%20print%28%29%0A%20%20%20%20%20%20%20%20%0AprintCoordinates%283,%203%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false', width=1300, height=800)
<IPython.lib.display.IFrame at 0x233782b5850>
如果换成 *
呢?
In [17]
def Stars(n, m):
# 输出一个 n*m 的星型矩阵图
for row in range(n):
for col in range(m):
print("*", end="")
print()
In [18]
Stars(5, 5)
*****
*****
*****
*****
*****
换一种写法
In [19]
# be careful! 这些代码与之前的有什么不同?
def printMysteryStarShape(n):
for row in range(n):
print(row, end=" ")
for col in range(row):
print("*", end=" ")
print()
In [20]
printMysteryStarShape(5)
0
1 *
2 * *
3 * * *
4 * * * *
In [21]
from IPython.display import IFrame
IFrame('https://pythontutor.com/visualize.html#code=%23%20be%20careful!%20%E8%BF%99%E4%BA%9B%E4%BB%A3%E7%A0%81%E4%B8%8E%E4%B9%8B%E5%89%8D%E7%9A%84%E6%9C%89%E4%BB%80%E4%B9%88%E4%B8%8D%E5%90%8C%EF%BC%9F%0A%0Adef%20printMysteryStarShape%28n%29%3A%0A%20%20%20%20for%20row%20in%20range%28n%29%3A%0A%20%20%20%20%20%20%20%20print%28row,%20end%3D%22%20%22%29%0A%20%20%20%20%20%20%20%20for%20col%20in%20range%28row%29%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print%28%22*%22,%20end%3D%22%20%22%29%0A%20%20%20%20%20%20%20%20print%28%29%0A%20%20%20%20%20%20%20%20%0AprintMysteryStarShape%285%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false', width=1300, height=800)
<IPython.lib.display.IFrame at 0x233781b3a60>
while 循环
嘿!
当你不知道循环什么时候停下来的时候,为什么不试试 while
找出一个数最左边的那一位的数值(12345
的 1
)
In [22]
# 我不知道它什么时候停下来
def leftmostDigit(n):
n = abs(n)
while n >= 10:
n = n//10
return n
In [23]
leftmostDigit(46535248)
4
举个例子:依次找出 n 个 4 或者 7 的整数倍非负整数
In [24]
def isMultipleOf4or7(x):
return ((x % 4) == 0) or ((x % 7) == 0)
def nthMultipleOf4or7(n):
found = 0
guess = -1
while found <= n:
guess += 1
if isMultipleOf4or7(guess):
found += 1
return guess
In [25]
print("4 或 7 的倍数: ", end="")
for n in range(15):
print(nthMultipleOf4or7(n), end=" ")
4 或 7 的倍数: 0 4 7 8 12 14 16 20 21 24 28 32 35 36 40
Bad Style:在知道循环范围的情况下使用 while
In [26]
def sumToN(n):
# 尽管它能正确运行,但是这是非常不推荐的做法!
# 应该使用 for 循环而不是 while 循环
total = 0
counter = 1
while counter <= n:
total += counter
counter += 1
return total
In [27]
sumToN(5) == 1+2+3+4+5
True
break 与 continue 语句
In [28]
for n in range(200):
if n % 3 == 0:
continue # 跳过这次循环
elif n == 8:
break # 跳出当前整个循环
else:
pass # 啥也不做,占位符(不会被运行)
print(n, end=" ")
1 2 4 5 7
假·死循环
与环境交互后,在特定条件下终止的循环
In [29]
# 不需要看懂这些代码,关注演示的过程
def readUntilDone():
linesEntered = 0
while True:
response = input("输入一个字符串(输入 done 则退出): ")
if response == "done":
break
print("你输入了: ", response)
linesEntered += 1
print("Bye!")
return linesEntered
In [30]
linesEntered = readUntilDone()
print("你输入了", linesEntered, "行 (不包括 'done').")
你输入了: learn
你输入了: python
你输入了: the
你输入了: smart
你输入了: way
Bye!
你输入了 5 行 (不包括 'done').
isPrime
判断一个数是不是质数
In [31]
# 不是最快的写法,但最容易理解
def isPrime(n):
if n < 2:
return False
for factor in range(2,n):
if n % factor == 0:
return False
return True
In [32]
for n in range(100):
if isPrime(n):
print(n, end=" ")
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
faster IsPrime:
In [33]
# 快了一点
def fasterIsPrime(n):
if n < 2:
return False
if n == 2:
return True
if n % 2 == 0:
return False
maxFactor = round(n**0.5)
for factor in range(3, maxFactor+1, 2):
if n % factor == 0:
return False
return True
In [34]
for n in range(100):
if fasterIsPrime(n):
print(n, end=" ")
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
真的快了?
In [35]
# 验证他它俩结果是一样的
for n in range(100):
assert(isPrime(n) == fasterIsPrime(n))
print("两种解法的结果一致")
两种解法的结果一致
In [39]
import time
bigPrime = 102030407
print("Timing isPrime(",bigPrime,")", end=" ")
# isPrime
time0 = time.time()
print(", returns ", isPrime(bigPrime), end=" ")
time1 = time.time()
print(", time = ",(time1-time0)*1000,"ms\n")
# fasterIsPrime
print("Timing fasterIsPrime(",bigPrime,")", end=" ")
time0 = time.time()
print(", returns ", fasterIsPrime(bigPrime), end=" ")
time1 = time.time()
# result
print(", time = ",(time1-time0)*1000,"ms")
Timing isPrime( 102030407 ) , returns True , time = 4708.568811416626 ms
Timing fasterIsPrime( 102030407 ) , returns True , time = 0.4515647888183594 ms
nth Prime
依次找出第 n 位质数
In [37]
def nthPrime(n):
found = 0
guess = 0
while found <= n:
guess += 1
if fasterIsPrime(guess):
found += 1
return guess
In [38]
for n in range(10):
print(n, nthPrime(n))
print("Done!")
0 2
1 3
2 5
3 7
4 11
5 13
6 17
7 19
8 23
9 29
Done!
总结
- For 循环用于指定范围的重复操作。
range()
可以生成一个数字范围。- 在不知道循环什么时间停止的时候,应该试试 While 循环。
- 循环同样也是可以嵌套的。
- 巧妙地使用
break
和continue
语句。 - 合理的剪枝,缩小搜索范围/循环范围,可以大幅提高程序运行效率。
$\textcolor{red}{本文部分引用自网络}$
$\textcolor{red}{文章架构来源于课程ppt(免责声明)}$
标签:return,05,range,笔记,Datewhale,20%,print,total,def From: https://www.cnblogs.com/liuyunhan/p/17859342.html