python(函数/方法)

主要解决的问题:

        将那些具有独立性功能的,且重复的代码进行封装

        这一段代码,专门用于处理某一个问题

比如素数问题:

a = 10
b = 110
c = 129087
# 哨兵:监控状态变化
flag = True # 默认是素数
for n in range(2, a // 2 + 1):
    if a % n == 0:
        flag = False
        break
if flag:
    print("YES")
else:
    print("No")
    
# 哨兵:监控状态变化
flag = True # 默认是素数
for n in range(2, b // 2 + 1):
    if b % n == 0:
        flag = False
        break
if flag:
    print("YES")
else:
    print("No")
# 哨兵:监控状态变化
flag = True # 默认是素数
for n in range(2, c // 2 + 1):
    if c % n == 0:
        flag = False
        break
if flag:
    print("YES")
else:
    print("No")

到底什么是函数:

就是一个具有固定功能的一段代码,根据不同输入的参数,进行同样的计算,得到了不同的结果

python当中 函数的语法格式:

def 函数名(参数列表):
 函数体,具体的执行内容
 return 返回值   
# 如果函数不需要返回 则可以不写return
# return 它仅仅表示结束当前函数 如果有返回值则写上 没返回值可以不写return 默认返回None
# 函数必须先定义 再调用(除了面向对象在类中定义函数时)

素数问题进行函数化:

# 素数问题
def isSushu(num):
    for n in range(2, num // 2 + 1):
        if num % n == 0:
            return False
    return True
# TypeError: isSushu() missing 1 required positional argument: 'num'
# NameError: name 'isSushu' is not defined
# isSushu()
def isSushuNoReturn(num):
    for n in range(2, num // 2 + 1):
        if num % n == 0:
            print(False)
            return
    print(True)
    return # 其实可以不写 但是存在 (隐藏的)
# print(isSushu(11))
print(isSushuNoReturn(11))

关于函数局部变量的一些问题:

n = 10
def test01(n):
    #局部变量n 用于接受外部变量的数据
    n = 20 #n是test01内部创建的一个变量
test01(n)
print(n)

arr = [1,2,3]
def test02(arr):
    #局部变量arr 用于接受外部变量的数据
    arr[0] = 666 #arr是test02内部创建的一个变量
test02(arr)
print(arr)

n = 100
def test03():
    n = 200 #函数内部创建的变量
    m = 300 #函数内部创建的变量
test03()
print(n)
print(m) #NameError: name 'm' is not defined

在函数的外面,并不能调用函数内部创建的变量(局部变量)

        一定要区分,在函数内部

                操作的变量是局部还是全局的

                =是创建还是修改

n = 100
def test04(n): # n 是以局部变量的形式创建的 然后在接收全局n的100
    n = 200 # 修改
    m = 300 # 创建
test04(n)
print(n)
print(m)

如何修改外部变量,用 global 关键字去指定

n = 100
m = 300
def test05():
    n = 666
    print(n)
    global n, m # 事先指定哪些变量是全局的
    n = 200
    m = 400
    print(n)
    # SyntaxError: name 'n' is used prior to global declaration
    # 在函数内部 局部变量和全局变量 不要重名
test05()
print(n)
print(m)
n = 100
m = 300
def test06():
    global n
    n = 200 # 已经被声明为全局
    m = 400 # 局部变量
test06()
print(n, m)
def test07(arr): # 局部变量 函数被调用时 指向[1,2,3]
    arr = [2, 3, 4] # 被修改 指向[2,3,4]
arr = [1, 2, 3]
test07(arr)
print(arr)

python主函数的问题

函数还能将代码进行模块化,解耦,方便阅读、维护、设计

# 程序的入口 看成主函数
if __name__ == "__main__":
    print("Hello World")

关于函数的具体执行的流程

        函数的运行 是基于栈内存的

        每一个函数看作是栈内存元素

        哪个函数在栈顶 那么它就优先执行 直到调用别的函数 当前函数暂停执行

        函数但凡被调用 则加载到栈内存中 成为新的栈顶

        函数执行完毕(遇到return)则弹栈 新的栈顶继续执行

递归

# 递归
def show():
    arr = [0] * 1000000000000000 # MemoryError 堆内存溢出
    print("show") # RecursionError: maximum recursion depth exceeded 栈内存溢出
    show()
def main():
    show()
if __name__ == "__main__":
    main()

所谓的递归 其实就是函数自身调用自身

栈内存溢出 栈主要存函数的 函数存不下了(主要还是因为递归)

堆内存溢出 堆主要存对象的 对象存不下了(一直在创建新的数据对象)

递归的应用

递归如果设计不当,容易导致占内存溢出

所以之后在写递归的时候,需要注意啥?注意递归什么时候结束!

递归,它可以将一个大型复杂的问题,进行逐层的化解,化为若干个较小的问题,同时这些较小的 问题也可继续进行化解为若干个更小的问题,直到该问题不能被化解为止(终止递归)->原子问题 是可以直接被求解的

所以,将所有原子问题的解,进行合并,就得到了原问题的解

        原子问题之间的求解,不能相互作用,互不影响!

        每一层问题的求解方式,都是一致的!

上述的内容,就是【分治算法】

但凡是迭代的问题,都可以被递归写,但反过来就不一定了

同样的一个问题,用迭代写的代码较多,用递归写的代码较少

递归可以用少量的代码来解决较大的问题

人用迭代,神用递归

(1)计算1~100之间的求和问题

# (1)计算1~100之间的求和问题
"""
f(100) = 1+2+3+4+....+99+100
f(99) = 1+2+3+4+...+98+99
f(n) = f(n - 1) + n
f(100) = f(99) + 100
f(99) = f(98) + 99 1+2+3+...+98 + 99
....
f(4) = f(3) + 4 1+2+3 + 4
f(3) = f(2) + 3 1+2 + 3
f(2) = f(1) + 2 1 + 2
f(1) = 1 # 递归的边界条件
f(100)->f(1) 递归的前进段
f(1) = 1 递归的边界条件
f(1)->f(100) 递归的返回段
1, n = 1
f(n)
f(n-1) + n, n > 1
"""
def nSum(n):
    if n == 1:
        return 1
    return nSum( n - 1 ) + n

(2)斐波那契数列

        是一串整数,其中每个数字是前两个数字的和,从0和1开始。数列的前几个数字是:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...
#(2)斐波那契数列
"""
1 1 2 3 5 8 13 21 34 55 89 ...
f(n) = f(n-1) + f(n-2)
f(5)
f(4) + f(3)
f(3) + f(2) f(2) + f(1)
f(2) + f(1)
1, n ∈[1,2]
f(n)
f(n-1) + f(n-1), n > 2
"""
def fibo(n):
    if n == 1 or n == 2:
        return 1
    return fibo(n - 1) + fibo(n - 2)

(3)二分查找

def binarySearch(arr , L , R , key):
    if L > R :
        return -1
    M = (L + R) // 2
    if arr[M] == key:
        return M
    elif arr[M] < key:
        return binarySearch(arr , M+1 , R , key)
    elsr:
        return binarySearch(arr , L , M-1 , key)

def main():
    print(nsum(100))
    #print(fibo(40))
    arr = [1,2,3,4,5,6,7,8,9,10]
    key = 11
    print(binarySearch(arr , 0 , len(arr) - 1 , key))

if__name__ == "__main__"
    main()

(4) 快速排序(三路快速排序)

import random
def quicksort(arr , L , R):
    if L > R:
        return
    lt = L
    gt = R + 1
    idx = random.randint(0 , R - L) + L
    arr[L], arr[idx] = arr[idx], arr[L]
    V = arr[L]
    i = L + 1
    while i < gt:
        if arr[i] < V:
            arr[lt + 1], arr[i] = arr[i], arr[lt + 1]
            lt += 1
            i += 1
        elif arr[i] > V:
            gt -= 1
            arr[gt], arr[i] = arr[i], arr[gt]
        else:
            i += 1
    arr[L], arr[lt] = arr[lt], arr[L]
    # 递归处理左边
    quickSort(arr, L, lt - 1)
    # 递归处理右边
    quickSort(arr, gt, R)
def main():
    global count
    arr = [0] * 50
    for i in range(len(arr)):
        arr[i] = random.randint(0,1000)
    quickSort(arr, 0, len(arr) - 1)
    print(arr)
if __name__ == "__main__":
    main()

(5) 汉诺塔问题

"""
前3个 X -> Z
    前2个 X -> Y
        前1个 X -> Z
        第2个 X -> Y
        前1个 Z -> Y
    第3个 X -> Z
    前2个 Y -> Z
        前1个 Y -> X
        第2个 Y -> Z
        前1个 X -> Z
"""

def hanoi(n , begin , mid , end):
    if n == 1:
        print(begin + " -> " + end)
    else:
        hanoi(n-1 , begin , end , mid)
        print(begin + " -> " + end)
        hanoi(n-1 , mid , begin ,end)

def main():
    X = "X"
    Y = "Y"
    Z = "Z"
    hanoi(3 , X , Y ,Z)

if __name__ == "__main__" :
    main()

(6) 全排列

#全排列问题
"""
"ABC"
ABC
ACB
BAC
BCA
CAB
CBA
"""
result = [] # set集合适用于去重复的操作
def permutation(arr , left , right):
    if left == right:
        s = ""
        for c in arr:
            s += c
        if s not in result:
            result.append(s)
    else:
        for i in range(left , right + 1):
            arr[i] , arr[left] = arr[left] , arr[i]
            permutation(arr , left + 1 , right)
            arr[i] , arr[left] = arr[left] , arr[i]

def main():
    s = input()
    arr = list(s)
    permutation(arr , 0 , len(arr) - 1)
    print(result)

if __name__ == "__main__" :
    main()

关于二维数组的补充

"""
二维列表
所谓的二维列表 本质上还是一个一维列表
只不过该一维列表中 的每一个元素 又是另一个一维列表而已
"""
arr = [1,2,3]
matrix = [[1,2,3],[4,5,6],[7,8,9]]
print(matrix[0])
print(matrix[0][1])
#锯齿二维数组
matrix = [[1,2,3],
    [1,2,3,4,5],
    [7,8]]
#二维数组的遍历
for i in range(len(matrix)):
    for j in range(len(matrix[i])):
        print(matrix[i][j])
#如何去创建一个指定宽高/行列 但是没有元素的空二维数组
row = 5
col = 8
matrix = [0] * row
print(matrix)
for i in range(row):
    matrix[i] = [0] * col
print(matrix)
for i in range(len(matrix)):
    for j in range(len(matrix[i])):
        print(matrix[i][j],end = " ")
    print()

利用二维数组,来去实现一个五子棋游戏 棋盘 15×15

#用于区分黑白棋 奇偶性 统计棋子的个数
player = 0

#棋盘设置
def creatBoard(size):
    board = [None] * size
    for i in range(size):
        board[i] = ["+"] * size
    return board

def printBoard(board):
    for i in range(len(board)):
        for j in range(len(board[i])):
            print(board[i][j], end = " ")
        print()

#下棋的逻辑
def playChess(chess , board):
    global player
    row = int(input(">>>请输入行:")) - 1
    col = int(input(">>>请输入列:")) - 1
    if board[row][col] == "+" :
        board[row][col] = chess
    else:
        print(">>>此处已存在棋子,请重新下棋")
        player -= 1
    printBoard(board)

#判断游戏是否结束(五子连珠 或者 和棋)
def isGameOver(board):
    global player
    for row in range(len(board)):
        for col in range(len(board[row])):
            #如果有“+”,表示有空格出现,则没有五子连珠或和棋
            if board[row][col] == "+" :
                continue
            #向右
            if col < 11:
                if board[row][col] == board[row][col + 1] == board[row][col + 2] == board[row][col + 3] == board[row][col + 4]:
                    return True
            #向下
            if row < 11:
                if board[row][col] == board[row + 1][col] == board[row + 2][col] == board[row + 3][col] == board[row + 4][col]:
                    return True
            #向右下
            if row < 11 and col < 11:
                if board[row][col] == board[row + 1][col + 1] == board[row + 2][col + 2] == board[row + 3][col + 3] == board[row + 4][col + 4]:
                    return True
            #向右上
            if row > 3 and col < 11:
                if board[row][col] == board[row - 1][col + 1] == board[row - 2][col + 2] == board[row - 3][col + 3] == board[row - 4][col + 4]:
                    return True
            if player == 15 * 15:
                return True
        return False

def main():
    global player
    #创建棋盘
    board = creatBoard(15)
    #打印棋盘
    printBoard(board)
    #游戏逻辑
    while not isGameOver(board):
        if player % 2 == 0:
            print(">>>请黑方下棋")
            playChess("●", board)
        else:
            print(">>>请白方下棋")
            playChess("○", board)
        player += 1
    if player % 2 == 1:
        print(">>黑棋胜!")
    else:
        print(">>白棋胜!")


if __name__ == "__main__":
    main()

N皇后问题(递归)

"""
N皇后问题(递归)
"""
N = 4  #几皇后问题
#构建二维数组
arr = [0] * N
for i in range(N) :
    arr[i] = [0] * N
count = 0

def isDangerous(row , col): #判断是否危险(是否可以成为皇后) True为不可以 Flase为可以
    #正上
    r = row - 1
    while r >= 0:
        if arr[r][col] == 1: #如果上面有皇后
            return True  #直接结束循环
        r -= 1 #继续向上一行判断
    #左上
    r = row - 1
    c = col - 1
    while r >= 0 and c >=0:
        if arr[r][c] == 1:
            return True
        r -= 1
        c -= 1
    #右上
    r = row - 1
    c = col - 1
    while r >= 0 and c < N :
        if arr[r][c] == 1:
            return True
        r -= 1
        c += 1
    return False #以上全都没有返回False则为不危险

def nQueen(row):  #row从第一行开始向下遍历到 N 行
    global count
    if row == N:  #如果row从上到下遍历完 N 层 , 表示一种结果产生
        count += 1
        print(f"第{count}种解:")  #打印这是第几种解法
        #打印这个矩阵
        for i in range(len(arr)):
            for j in range(len(arr[i])):
                print(arr[i][j] , end = " ")
            print()
    else:
        for col in range(N):
            if not isDangerous(row , col): #如果不危险 则这个格子可以是皇后
                arr[row][col] = 1  #第row行col个格子标记为这行的皇后
                nQueen(row + 1)   #row向下移一行继续判断
                arr[row][col] = 0  #当前行走完了没有到下一行得清零

def main():
    nQueen(0)

if __name__ == "__main__":
    main()

函数编程练习(55,56,68,72)

Demo55 测试密码

题目描述
一些网站会给密码强加一些规则:
1 )密码必须至少有 8 个字符
2 )密码只能包含英文字母和数字
3 )密码应该至少包含两个数字
4 )密码应该至少包含两个大写字母
如果密码符合规则,输出 Yes ;否则输出 No
输入输出描述
输入一串密码
输出该密码是否符合规则
s = input()
flag = True  #哨兵:假设所设置密码合格
if len(s) < 8:  #判断密码长度
    print("密码至少8个字符") 
    flag = False
dx = 0  #是否为大写
sz = 0  #是否有数字
for i in s : 
    if i.isupper(): #判断是否为大写
        dx += 1
    if i.isupper(): #判断是否有数字
        sz += 1
if dx < 2:  #如果大写小于2个
    print("密码至少两大写")
    flag = False
if sz < 2: #如果数字小于2个
    print("密码至少两数字")
    flag = False
for j in s:
    if i.isupper() and i. isupper(): #大写和数字是否同时有
        flag = True
if flag == True:
    print("通过")
else:
    print("错误")

Demo56 回文素数

题目描述
回文素数是指一个数既是素数又是回文数,例如 131 既是素数也是回文数
输出显示前 100 个回文素数,每行显示 10
def is_zhishu(num):
    for i in range(2, num // 2 + 1):
        if num % i == 0:
            return False
 
    return True

def is_huiwenshu(num):
    if str(num) == str(num)[::-1]:
        return True
 
count = 0
num = 2
while count < 100:
    if is_zhishu(num) and is_huiwenshu(num):
        print("%5d" % num, end=" ")
        count += 1
 
        if count % 10 == 0:
            print()
    num += 1

Demo68 豆机器

import random
def createPath(length):
    path = ""
    for i in range(length):
        if random.randint(0 , 1) == 1:  #[0 , 1]
            path = path + "R"
        else:
            path += "L"
    return path

def countR(path):
    count = 0
    for C in path:
        if C == "R":
            count += 1
    return count

def main():
    arr = input().split(" ")
    balls = int(arr[0]) #球的个数
    slots = int(arr[1]) #槽子的个数
    box = [0] * slots   #槽子数组
    for i in range(balls):
        path = createPath(slots - 1)
        print(path)
        index = countR(path)
        box[index] += 1
    print(box)

if __name__ == "__main__" :
    main()

Demo72 猜单词游戏

题目描述
随机产生一个单词,然后提示用户一次猜一个字母,如下示例所示。单词中的每个字母都显示为一个 # 号,当用户猜测正确时就会显示确切的字母,当用户完成一个单词时,显示失误的次数并询问用户是否 继续玩游戏
创建一个数组存储备选单词,然后随机从中抽取进行游戏
import random
#根据明文单词和状态 构建密文
def createPasswd(word , state):
    passwd = ""
    for i in range(len(word)):
        if state[i]:
            passwd += "#"
        else:
            passwd += word[i]
    return passwd

#游戏是否结束 True结束
def isGameOver(state):
    return True not in state

#修改状态 True修改成功 False未修改(已存在)
def isChangeState(state):
    return True not in state

def isChangeState(state , word , ch):
    for i in range(len(word)):
        if word[i] == ch:
            if state[i]:
                state[i] = False
            else:
                return False
    return True
def main():
    #单词组
    words = ["banana" , "orange" , "computer" , "refrigerator" , "program"]
    while True:
        #明文单词
        word = words[random.randint(0 , len(words) - 1)]
        #单词状态
        state = [True] * len(word)
        #制作密文
        passwd = createPasswd(word , state)
        #错误次数
        missed = 0
        while not isGameOver(state):
            #输入一个字母
            ch = input("Enter a letter in word" + passwd + ">")
            #判断在不在
            #如果在 判断是否已修改
            if ch in word:
                
                if isChangeState(state , word , ch):
                    passwd = createPasswd(word , state)
                else:
                    print(ch + "is not in the word")
            #如果不在统计次数
            else:
                missed += 1
                print(ch + " is not in the word")
        #提示单词 错误次数
        print(f"The word is {word}. You missed {missed} time")
        #询问是否继续
        choice = input("是否继续? y/n >")
        if choice == "n":
            break

if __name__ == "__main__" :
    main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值