函数进阶
创建函数
def 语句
- 标题行由 def 关键字、函数的名字,以及参数的集合(如果有的话)组成
- def 子句的剩余部分包括了一个虽然可选但是强烈推荐的文档字串,和必需的函数体
前向引用
- 函数不允许在函数未声明之前,对其进行引用或者调用
def foo(): # 定义函数foo(),先调用bar()函数,报错,下面定义以后,报错取消
print('in foo')
bar()
def bar(): # 定义函数bar()
print('in bar')
foo() # 函数foo()已经被定义,可以直接调用
注意
- 定义函数时,函数的先后顺序不重要,重要的是 函数在什么位置被调用
调用函数
- 使用一对圆括号() 调用函数,如果没有圆括号,只是对函数的引用
- 任何输入的参数都是必须放置在括号中
>>> def foo(): # 定义函数foo()
... print('in foo')
...
>>> foo # 调用函数时,函数名后必须有小括号,否则返回一个位置对象
>>> foo() # 函数得正确调用方式
关键字参数
- 关键字参数的概念仅仅针对函数的调用
- 这种理念是 让调用者通过函数调用中的参数名字来区分参数
- 这种规范允许参数不按顺序
- 位置参数应写在关键字参数前面
# 默认参数:定义函数,给形参的默认值
def get_info(name, age=20):
print("%s is %s years old" % (name, age))
# 按照位置传参
get_info("nfx") # name="nfx" age=20
get_info("nfx", 18) # name="nfx" age=18
get_info(18, "nfx") # name=18 age="nfx"
# 关键字传参(指名道姓): 可以不按照顺序传参
get_info(name="nfx", age=18)
get_info(age=18, name="nfx")
# 注意: 关键字参数后不能有位置参数
get_info("nfx", age=20)
# get_info(name="nfx", 20): 报错
print("hello", "world", sep="---", end="!!\n")
练习:简单的加减法数学游戏
需求
- 随机生成两个100以内的数字
- 随机选择加法或是减法
- 总是使用大的数字减去小的数字
import random
def exam():
nums = [random.randint(1,100) for i in range(2)]
nums.sort(reverse=True)# 列表降序排列 [大数, 小数]
tmp = random.choice("+-") # 随机出操作符
# result: 是题目的正确答案
if tmp == "+":
result = nums[0] + nums[1]
else: # tmp == "-"
result = nums[0] - nums[1]
# 10 + 5 = ?? 请作答: answer: 计算的答案
answer = int(input("%s %s %s = ?? 请作答: " % (nums[0], tmp, nums[1])))
if answer == result:
print("Very Good~~~")
else:
print("Wrong answer!!!")
def show_menu():
while True:
exam()
tmp = input("退出(n/N): ") # 只限制退出
if tmp in ["n", "N"]:
print("Byebye~")
break
if __name__ == '__main__':
show_menu()
匿名函数
- python 允许用 lambda 关键字创造匿名函数
- 匿名是因为不需要以标准的 def 方式来声明
- 一个完整的 lambda "语句"代表了一个表达式,这个表达式定义体必须和声明放在同一行
def add(x, y):
return x+y
def func01(num):
# if num % 2 == 1:
# return True
# else:
# return False
# if表达式
return True if num % 2 == 1 else False
test = lambda num: True if num % 2 == 1 else False
print(test(100)) # False
myadd = lambda x, y: x+y # 显示调用不推荐
print(myadd(100, 200)) # x = 100, y = 200
print(add(1, 2))
filter() 函数
- filter(func, seq): 调用一个布尔函数 func 来迭代遍历每个序列中的元素;返回一个使 func 返回值为 true 的元素的序列
- 如果布尔函数比较简单,直接使用 lambda 匿名函数就显得非常方便了
filter(func, seq)函数的使用,如果seq序列中的元素,传入函数func后,返回值为True,则保留下来
# filter(布尔函数, 列表):
# 让列表中的元素经过布尔函数的过滤
# 将过滤结果为True的元素留下,False的元素扔掉
def func01(num):
# if num % 2 == 1:
# return True
# else:
# return False
return True if num % 2 == 1 else False
def func02(num):
# if num > 5:
# return True
# else:
# return False
return True if num > 5 else False
# def func03(num):
# return True if num % 2 == 0 else False
if __name__ == '__main__':
list01 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
data1 = filter(func01, list01) # 1 3 5 7 9
print("data1:", list(data1)) # [1, 3, 5, 7, 9]
data2 = filter(func02, list01) # 6 7 8 9 10
print("data2:", list(data2)) # [6, 7, 8, 9, 10]
# data3 = filter(func03, list01)
data3 = filter(
lambda num: True if num % 2 == 0 else False,list01
)
print("data3:", list(data3)) # [2, 4, 6, 8, 10]
# 匿名函数过滤
d4=filter(lambda num:True if num>6 else False,list01)
print("data4:", list(d4)) # [7, 8, 9, 10]
map() 函数
- map(func,seq): 调用一个函数func 来迭代遍历每个序列中的元素;返回一个经过func处理过的元素序列
map(func, seq)函数的使用,将seq序列中的元素,传入函数func后,经过处理后全部保留下来
# map(加工函数, 列表):将列表中的每一个元素统一经过函数处理
def func01(num):
return num * 2 + 10
if __name__ == '__main__':
list01 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
data1 = map(func01, list01)
print("data1:", list(data1))
# [12, 14, 16, 18, 20, 22, 24, 26, 28, 30]
# 匿名函数
data2 = map(lambda num: num+5, list01)
print("data2:", list(data2))
# map: 传布尔函数的情况
d3 = map(lambda num:True if num>5 else False,list01)
print("data3:", list(d3))
# [False, False, False, False, False, True, True, True, True, True]
总结