函数
工具函数
绝对值函数
python
print("绝对值函数:", abs(100), abs(-120), abs(12.34))
绝对值函数: 100 120 12.34
返回最大值
python
print("返回最大值:", max(1, 2), max(2, 3, 1, -5))
返回最大值: 2 3
返回最小值
python
print("返回最小值:", min(1, 2), min(2, 3, 1, -5))
返回最小值: 1 -5
进制转换
python
print(hex(255), hex(1000))
0xff 0x3e8
数据类型转换
python
print("整型 int: ", int("123"), int(12.34), type(int("123")), type(int(12.34)))
print("浮点型 float: ", float("12.34"), type(float("12.34")))
print("字符型 str: ", str(1.23), type(str(1.23)), str(100), type(str(100)))
print("布尔型 bool: ", bool(1), type(bool(1)), bool(""), type(bool("")))
整型 int: 123 12 <class 'int'> <class 'int'>
浮点型 float: 12.34 <class 'float'>
字符型 str: 1.23 <class 'str'> 100 <class 'str'>
布尔型 bool: True <class 'bool'> False <class 'bool'>
函数定义
对参数类型检查
python
def my_abs(x):
if not isinstance(x, (int, float)):
raise TypeError("Bad operand type")
if x >= 0:
return x
else:
return -x
空函数 pass 占位
python
def nop():
pass
函数返回多个值
python
import math
def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny
r = move(100, 100, 60, math.pi / 6)
x, y = move(100, 100, 60, math.pi / 6)
print("返回值:", r, x, y)
返回值: (151.96152422706632, 70.0) 151.96152422706632 70.0
默认参数
- 默认参数必须指向不变对象
python
def power(x, n=2):
s = 1
while n > 0:
n -= 1
s *= x
return s
print(power(5), power(5, 3))
25 125
- 多个默认参数
python
def enroll(name, gender, age=6, city="beijing"):
return f"name: {name}, gender: {gender}, age: {age}, city: {city}"
print(enroll("Search", "F"))
print(enroll("Bob", "M"))
# 不按照默认顺序传参
print(enroll("Adam", "M", city="shanghai"))
name: Search, gender: F, age: 6, city: beijing
name: Bob, gender: M, age: 6, city: beijing
name: Adam, gender: M, age: 6, city: shanghai
- 默认参数为可变对象
python
def add_end(L=None):
if L is None:
L = []
L.append("END")
return L
print(add_end())
['END']
可变参数 *
允许传入 0 个或任意个参数,在函数调用时自动组装为一个 tuple
- 传递 list 或 tuple
python
def calc(numbers):
sum = 0
for n in numbers:
sum += n**2
return sum
print(calc([1, 2, 3]), calc((1, 3, 5, 7)))
14 84
- 可变参数的传递形式
python
def calc_dynamic(*numbers):
sum = 0
for n in numbers:
sum += n**2
return sum
print(calc_dynamic(1, 2, 3))
print(calc_dynamic(1, 3, 5, 7))
nums1 = [1, 2, 3]
nums2 = [1, 3, 5, 7]
print(calc_dynamic(nums1[0], nums1[1], nums1[2]))
print(calc_dynamic(*nums2))
14
84
14
84
关键字参数 **
关键字参数允许传入 0 个或任意个含参数名的参数,在函数内部自动组装为一个 dict 字典
关键字参数可以扩展函数的功能,可以用作可选项
python
def person(name, age, **kw):
print(f"name: {name}, age: {age}, other: {kw}")
person("Michael", 20)
person("Bob", 35, city="beijing")
person("Adam", 45, gender="M", job="Engineer")
dict1 = {"city": "beijing", "job": "Engineer"}
person("Jack", 24, city=dict1["city"], job=dict1["job"])
person("Jack", 24, **dict1)
name: Michael, age: 20, other: {}
name: Bob, age: 35, other: {'city': 'beijing'}
name: Adam, age: 45, other: {'gender': 'M', 'job': 'Engineer'}
name: Jack, age: 24, other: {'city': 'beijing', 'job': 'Engineer'}
name: Jack, age: 24, other: {'city': 'beijing', 'job': 'Engineer'}
命名关键字参数
分隔符号 *
后的参数被认为是命名关键字参数
- 检查关键字参数重是否包含 city 和 job 参数
python
def person_name(name, age, **kw):
if "city" in kw:
pass
if "job" in kw:
pass
print(f"name: {name}, age: {age}, other: {kw}")
# 这种方法仍旧可以绕过参数
person_name("Jack", 24, city="Beijing", addr="chaoyang", zipcode=123456)
name: Jack, age: 24, other: {'city': 'Beijing', 'addr': 'chaoyang', 'zipcode': 123456}
- 限制关键字参数名字
python
def person_limit(name, age, *, city, job):
print(name, age, city, job)
person_limit("Jack", 25, city="Beijing", job="Engineer")
Jack 25 Beijing Engineer
- 函数定义中存在了可变参数,后面的命名关键字参数就不需要分割符
*
python
def person_has_dynamic(name, age, *args, city, job):
print(name, age, args, city, job)
# 未传入参数名,调用将报错
# person_has_dynamic('Jack', 24, 'Beijing', 'Engineer')
- 命名关键字参数可以有缺省值,从而简化调用
python
def person_default_value(name, age, *, city="Beijing", job):
print(name, age, city, job)
person_default_value("Jack", 20, job="Player")
Jack 20 Beijing Player
参数祖合
定义顺序优先级:必选参数 > 默认参数 > 可变参数 > 命名关键字参数 > 关键字参数
python
def f1(a, b, c=0, *args, **kwargs):
print(f"a={a}, b={b}, c={c}, args={args}, kwargs={kwargs}")
def f2(a, b, c=0, *, d, **kwargs):
print(f"a={a}, b={b}, c={c}, d={d}, kwargs={kwargs}")
f1(1, 2)
f1(1, 2, c=3)
f1(1, 2, 3, "a", "b")
f1(1, 2, 3, "a", "b", x=9)
f2(1, 2, d=99, ext=None)
args = (1, 2, 3, 4)
kwargs = {"d": 99, "x": "#"}
f1(*args, **kwargs)
args = (3, 5, 7)
kwargs = {"d": True, "e": [], "x": "#"}
f2(*args, **kwargs)
a=1, b=2, c=0, args=(), kwargs={}
a=1, b=2, c=3, args=(), kwargs={}
a=1, b=2, c=3, args=('a', 'b'), kwargs={}
a=1, b=2, c=3, args=('a', 'b'), kwargs={'x': 9}
a=1, b=2, c=0, d=99, kwargs={'ext': None}
a=1, b=2, c=3, args=(4,), kwargs={'d': 99, 'x': '#'}
a=3, b=5, c=7, d=True, kwargs={'e': [], 'x': '#'}
递归函数
斐波那契
python
def fact(n):
if n == 1:
return 1
return n * fact(n - 1)
print(fact(1))
print(fact(100))
# 栈溢出
# print(fact(1000))
1
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
尾递归优化
return 语句不包含表达式
递归本身无论调用多少次,都只会用到一个栈帧,不会出现栈溢出的情况
python
def fact_call(n):
return fact_inter(n, 1)
def fact_inter(num, product):
if num == 1:
return product
return fact_inter(num - 1, num * product)
print(fact_inter(5, 1))
print(fact_inter(4, 5))
print(fact_inter(3, 20))
print(fact_inter(2, 60))
print(fact_inter(1, 120))
120
120
120
120
120
汉诺塔
请编写 move(n, a, b, c) 函数,它接收参数 n,表示 3 个柱子 A、B、C 中第 1 个柱子 A 的盘子数量,然后打印出把所有盘子从 A 借助 B 移动到 C 的方法
python
def move(n, a, b, c):
if n == 1:
print(a, "->", c)
else:
move(n - 1, a, c, b)
print(a, "->", "c")
move(n - 1, b, a, c)
move(3, "A", "B", "C")
A -> C
A -> c
C -> B
A -> c
B -> A
B -> c
A -> C