函数与模块化

对应教学日历:讲次 9-11


一、函数定义与调用

def 函数名([形式参数列表]):
    执行语句
    [return 返回值]
def mul(x, y):
    z = x * y
    return z
 
num1 = int(input("请输入第一个数:"))
num2 = int(input("请输入第二个数:"))
result = mul(num1, num2)
print("结果是%d" % result)

二、参数传递方式

1. 位置传递

def fun1(a, b):
    if a > b:
        return a
    else:
        return b
print(fun1(7, 3))  # 7

2. 关键字传递

def fun2(a, b):
    if a > b:
        return a
    else:
        return b
print(fun2(b=2, a=7))  # 7(位置无关)

3. 默认值参数传递

def fun3(a, b=2):
    if a > b:
        return a
    else:
        return b
print(fun3(7))   # 7(b使用默认值2)
 
def area(r=1.0, pi=3.14):
    return r * r * pi
print("面积1=%.2f" % area())              # 全部用默认值
print("面积2=%.2f" % area(5.1))           # 部分用默认值
print("面积3=%.2f" % area(5.1, 3.14159))  # 不用默认值

4. 元组类型变长参数(*args)

def mul(*number):
    print("元素为:", number)
    total = 1
    for i in number:
        total = total * i
    return total
print("结果为:", mul(2, 4))        # (2, 4), 8
print("结果为:", mul(1, 2, 3, 4, 5))  # (1,2,3,4,5), 120

5. 字典类型变长参数(**kwargs)

def func(**dict):
    print(dict)
    print(sum(dict.values()))
func(a=1, b=2, c=3)  # {'a': 1, 'b': 2, 'c': 3}, 6

三、lambda 匿名函数

# 普通函数
def f(x, y):
    return x + y
print("x+y=%d" % f(2, 3))
 
# lambda等价写法
z = lambda x, y: x + y
print("x+y=%d" % z(2, 3))

lambda 应用:字典排序

counts = {"C": 30, "Python": 53, "Java": 15, "C++": 42}
number = list(counts.items())
number.sort(key=lambda x: x[1], reverse=True)
print(number)  # [('Python', 53), ('C++', 42), ('C', 30), ('Java', 15)]

四、map() 函数

price = [35.8, 24.9, 23.5]
list(map(lambda x: x * 2, price))  # [71.6, 49.8, 47.0]
 
price1 = [35.8, 24.9, 23.5]
price2 = [88.5, 32.0, 12.9]
list(map(lambda x, y: x + y, price1, price2))  # [124.3, 56.9, 36.4]

五、高阶函数

def add(x, y):
    return x + y
def subtract(x, y):
    return x - y
def myfunc(x, y, f):
    return f(x, y)
print(myfunc(3, 5, add))       # 8
print(myfunc(3, 5, subtract))  # -2

函数名可以作为参数传递给另一个函数。

六、递归

阶乘

# 递归写法
def fac(n):
    if n == 1:
        return 1
    else:
        return n * fac(n - 1)
print(fac(5))  # 120

Fibonacci数列

# 递归写法
def fibs(num):
    if num == 1:
        return 1
    elif num == 2:
        return 1
    else:
        return fibs(num - 1) + fibs(num - 2)
for i in range(1, 101):
    print(fibs(i), end=" ")
 
# 循环写法
def fibs(num):
    result = [1, 1]
    for i in range(2, num):
        result.append(result[i-2] + result[i-1])
    return result
print(fibs(100))

汉诺塔

def hanoi(n, a, b, c):
    if n == 1:
        print('No.', n, ':', a, '-->', c)
    else:
        hanoi(n - 1, a, c, b)
        print('No.', n, ':', a, '-->', c)
        hanoi(n - 1, b, a, c)
hanoi(64, 'A', 'B', 'C')

最大公约数

# 递归写法
def gcd(x, y):
    if y == 0:
        return x
    else:
        return gcd(y, x % y)
 
# 循环写法
def gcd(x, y):
    while y != 0:
        q = x % y
        x = y
        y = q
    return x

七、变量作用域

a, b = 5, 6
def fun():
    a, b = 10, 15           # 局部变量
    print("函数内:a=%d, b=%d" % (a, b))
fun()                       # 函数内:a=10, b=15
print("函数外:a=%d, b=%d" % (a, b))  # 函数外:a=5, b=6

global 声明

C = 0
def modifyConstant():
    global C        # 声明使用全局变量
    C += 1
modifyConstant()
print(C)  # 1

作用域易错题

result = 2
def test(result, m):
    result = pow(result, m)
    print(result, end=" ")
test(result, 3)    # 8
print(result)      # 2
# 结果:8 2(函数内修改的是局部变量,不影响全局)

作业示例

五环图

from turtle import *
def draw(color, x, y):
    penup()
    goto(x, y)
    pendown()
    pencolor(color)
    circle(60)
    pensize(10)
    speed(10)
 
draw('blue', -150, 0)
draw('black', 0, 0)
draw('red', 150, 0)
draw('yellow', -75, -50)
draw('green', 75, -50)

用lambda调用不同数量的随机点名

def cal(num):
    aList = []
    with open("student.csv", 'r') as handle:
        for i in handle:
            i = i.strip()
            info = i.split(",")
            aList.append(info[1])
    result = random.sample(aList, num)
    for i in result:
        print("{},请回答问题.".format(i))
 
# tkinter中使用lambda传递参数
one = Button(root, text='点一名', command=lambda: cal(1))
three = Button(root, text='点三名', command=lambda: cal(3))

作业重点

  • 函数名后面即使无参数也要带空括号 ()
  • return 语句结束函数执行并返回值,没有return则返回None
  • 五种参数传递:位置、关键字、默认值、元组变长、字典变长
  • lambda 匿名函数只有一个表达式,常用于排序key和tkinter按钮
  • 递归两个要素:递推公式 + 结束条件(递归出口)
  • 局部变量与全局变量同名时,函数内部局部变量起作用
  • global 声明可在函数内修改全局变量
  • 函数名作为参数传递 = 高阶函数