admin管理员组

文章数量:1529453

目录

for 循环和循环范围

for 循环的特点

for 循环嵌套

while 循环

break 与 continue 语句

假·死循环

isPrime

faster IsPrime

nth Prime

矩阵操作

总结


for 循环和循环范围

for 循环的特点

基于提供的范围,重复执行特定次数的操作

def sumFromMToN(m, n):
    total = 0
    # 注意: range(x, y) 是左闭右开区间,包含 x,不包含 y
    for x in range(m, n+1):
        total += x
    return total
sumFromMToN(5, 10) == 5+6+7+8+9+10

注意是左闭右开区间所以为了让右闭,所以n+1

range()是个什么东西?——用于生成数列
其实在这里,我们也可以不用循环来完成同样的任务

如果我们省略第一个参数会发生什么?

def sumToN(n):
    total = 0
    # range 起始范围默认为 0
    for x in range(n+1):
        total += x
    return total

那如果我们添加第三个参数呢?

def sumEveryKthFromMToN(m, n, k):
    total = 0
    # 第三个参数为 “步长” step
    for x in range(m, n+1, k):
        total += x
    return total
​
sumEveryKthFromMToN(5, 20, 7) == (5 + 12 + 19)
True

只对从 m 到 n 的 奇数求和

# 我们也可以通过修改循环内部的代码来改变步长
​
def sumOfOddsFromMToN(m, n):
    total = 0
    for x in range(m, n+1):
        if x % 2 == 1:
            total += x
    return total
​
sumOfOddsFromMToN(4, 10) == sumOfOddsFromMToN(5,9) == (5+7+9)
True

现在我们反着来试一下!

# 我们将生成一个反向数字序列
# (仅供演示使用,代码实践中不建议这么做)
def sumOfOddsFromMToN(m, n):
    total = 0
    for x in range(n, m-1, -1):
        if x % 2 == 1:
            total += x
    return total
sumOfOddsFromMToN(4, 10) == sumOfOddsFromMToN(5,9) == (5+7+9)
True

反转也可以起到类似效果

for i in reversed(range(0, 10, 1):
        print(i)

还有更多方法来解决这个问题

for 循环嵌套

python的for循环非常慢,建议多层for循环采用python与c++的混合编程编写。

# 下面的代码将输出二维坐标
def printCoordinates(xMax, yMax):
    for x in range(1, xMax+1):
        for y in range(1, yMax+1):
            print(f"( {x} , {y} )  ", end="")
        print()
可以通过codetutor看整个打印过程Python compiler - visualize, debug, get AI help from ChatGPT (pythontutor)
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 )  

如果换成 * 呢?

def Stars(n, m):
    # 输出一个 n*m 的星型矩阵图
    for row in range(n):
        for col in range(m):
            print("*", end="")
        print()
Stars(5, 5)
*****
*****
*****
*****
*****

换一种写法

# be careful! 这些代码与之前的有什么不同?

def printMysteryStarShape(n):
    for row in range(n):
        print(row, end=" ")
        for col in range(row):
            print("*", end=" ")
        print()
printMysteryStarShape(5)
0 
1 * 
2 * * 
3 * * * 
4 * * * * 

外层循环的变量值控制内层循环的范围

while 循环

当你不知道循环什么时候停下来的时候,为什么不试试 while

找出一个数最左边的那一位的数值(12345 的 1 )

# 我不知道它什么时候停下来
​
def leftmostDigit(n):
    n = abs(n)
    while n >= 10:
        n = n//10
    return n

leftmostDigit(46535248)

4

举个例子:依次找出 n 个 4 或者 7 的整数倍非负整数

def isMultipleOf4or7(x):
    return ((x % 4) == 0) or ((x % 7) == 0)
​
def nthMultipleOf4or7(n):#找第n个4或7的倍数
    found = 0
    guess = -1
    while found <= n:
        guess += 1
        if isMultipleOf4or7(guess):
            found += 1
    return guess
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

def sumToN(n):
    # 尽管它能正确运行,但是这是非常不推荐的做法!
    # 应该使用 for 循环而不是 while 循环
    total = 0
    counter = 1
    while counter <= n:
        total += counter
        counter += 1
    return total
sumToN(5) == 1+2+3+4+5
True

不推荐使用,难懂。

break 与 continue 语句

for n in range(200):
    if n % 3 == 0:
        continue # 跳过这次循环
    elif n == 8:
        break # 跳出当前整个循环
    else:
        pass # 啥也不做,占位符(不会被运行)
    print(n, end=" ")
1 2 4 5 7 

continue会立马跳过该次循环不执行后面的语句;break跳出最近的这个整个循环

如果不想写一个for的变量,可以用_相当于一个黑洞,什么都可以装,不受任何变量影响

for _ in range(5)

假·死循环

与环境交互后,在特定条件下终止的循环

# 不需要看懂这些代码,关注演示的过程

def readUntilDone():
    linesEntered = 0
    while True:
        response = input("输入一个字符串(输入 done 则退出): ")
        if response == "done":
            break
        print("你输入了: ", response)
        linesEntered += 1
    print("Bye!")
    return linesEntered

输入一个字符串(输入 done 则退出):  learn
你输入了:  learn
输入一个字符串(输入 done 则退出):  python
你输入了:  python
输入一个字符串(输入 done 则退出):  the
你输入了:  the
输入一个字符串(输入 done 则退出):  smart
你输入了:  smart
输入一个字符串(输入 done 则退出):  way
你输入了:  way
输入一个字符串(输入 done 则退出):  done
Bye!
你输入了 5 行 (不包括 'done')

isPrime

判断一个数是不是质数

# 不是最快的写法,但最容易理解
​
def isPrime(n):
    if n < 2:
        return False
    for factor in range(2,n):
        if n % factor == 0:
            return False
    return True
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

# 快了一点
​
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
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 

真的快了?

# 验证他它俩结果是一样的
for n in range(100):
    assert(isPrime(n) == fasterIsPrime(n))
print("两种解法的结果一致")
两种解法的结果一致
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 =  6486.037492752075 ms

Timing fasterIsPrime( 102030407 ) , returns  True , time =  0.3590583801269531 ms

nth Prime

依次找出第 n 位质数

def nthPrime(n):
    found = 0
    guess = 0
    while found <= n:
        guess += 1
        if fasterIsPrime(guess):
            found += 1
    return guess
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!

矩阵操作

import  numpy as np #矩阵

import matplotlib.pyplot as plt #绘图

%matplotlib inline#直接显示在窗口

mat = np.random.randn(100,100)

mat.shape

num = mat.flatten() #拉平

plt.hist(num, bin=50) #绘制直方图 bin是绘制多少条柱子,越大效果会好一些

总结

  • For 循环用于指定范围的重复操作。
  • range() 可以生成一个数字范围。
  • 在不知道循环什么时间停止的时候,应该试试 While 循环。
  • 循环同样也是可以嵌套的。
  • 巧妙地使用 break 和 continue 语句。
  • 合理的剪枝,缩小搜索范围/循环范围,可以大幅提高程序运行效率。

本文标签: 法学聪明LoopPython