唐抉的个人博客

python学习笔记(三)

字数统计: 1.9k阅读时长: 8 min
2022/10/09

函数

python内置函数

绝对值:abs()

平方根:sqrt()

平方:power()

将整数转换为‘0x’前缀的十六进制字符串:hex()

将整数转换为‘0o’前缀的八进制字符串:oct()

数据类型转换函数:int()float()str()bool()

导包:import 包名

练习题

请利用Python内置的hex()函数把一个整数转换成十六进制表示的字符串:

1
2
3
4
5
# -*- coding: utf-8 -*-
n1 = 255
n2 = 1000
print(str(hex(n1)))
print(str(hex(n2)))

定义函数

def语句定义函数

如自定义一个abs函数并检验函数功能,其代码如下:

1
2
3
4
5
6
7
def my_abs(x):
if x>=0:
return x
else:
return -x
x=int(input())
print(my_abs(x))

在python交互环境中定义函数时,python会出现...的提示,函数定义结束后需要按两次回车使其重新回到>>>提示符下,如下图所示:

空函数

定义一个空函数,用pass语句来作为占位符。

1
2
def my_max():
pass

参数检查

如果要函数参数传入类型不对时需要抛出参数错误的信息,可用内置函数isinstance()检查参数,如if not isinstance(x,(int,float))语句,若传入了整数与浮点数之外的参数类型,函数就会抛出一个错误来提醒传参不对。

函数返回

函数体内部用return返回函数结果

函数执行完毕也没有return语句时,自动return None

函数的return可以返回多个值,值之间用半角逗号隔开,如return a,b

注意python返回值实际上是返回一个tuple,并非是返回两个值,比如以下代码:

1
2
3
4
5
6
7
8
9
10
def move(x,y):
return x+50,y+20
x=int(input())
y=int(input())
t=move(x,y)
print(t)、
#运行结果如下
50
100
(100, 120)

练习题

请定义一个函数quadratic(a, b, c),接收3个参数,返回一元二次方程 \[ ax^2+bx+c=0 \] 的两个解。

提示:

计算平方根可以调用math.sqrt()函数:

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# -*- coding: utf-8 -*-

import math

def quadratic(a,b,c):
t=math.sqrt(float(b*b-4*a*c))
p=(-b+t)/(2*a)
q=(-b-t)/(2*a)
return p,q

print('quadratic(2, 3, 1) =', quadratic(2, 3, 1))
print('quadratic(1, 3, -4) =', quadratic(1, 3, -4))

if quadratic(2, 3, 1) != (-0.5, -1.0):
print('测试失败')
elif quadratic(1, 3, -4) != (1.0, -4.0):
print('测试失败')
else:
print('测试成功')
#运行结果如下
quadratic(2, 3, 1) = (-0.5, -1.0)
quadratic(1, 3, -4) = (1.0, -4.0)
测试成功

默认参数

自定义函数可以设置默认参数。如次方函数可以设为默认平方,需要计算其他次方的时候再传次方的参数。代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def my_power(x,n=2):
t=1
while(n>0):
n=n-1
t=x*t
return t
x=int(input())
n=int(input())
print(my_power(x))
print(my_power(x,n))
#运行结果如下
3
4
9
81

注意:

  • 设置默认参数时。必选参数在前,默认参数在后
  • 当函数有多个参数时,变化大的参数放前面,变化小的参数可以作为默认参数
  • 默认参数必须指向不变对象

可变参数

传入的参数个数是可变的称为可变参数,形式为*参数名

可变参数允许传入0个或任意个参数,这些参数在函数调用时自动组装为一个tuple

在参数个数不确定时,定义可变参数和定义一个list和tuple参数相比,区别在于仅在参数前加了个*号,而在函数内部,参数接收到的是一个tuple,函数代码是完全不用变的。此时调用函数时可传入任意个参数calc(1,2)也可以传入0个参数clac()

将list或tuple元素变成可变参数传进函数中,可写成:

1
2
nums=[1,2,3]
calc(*nums)

关键字参数

关键字参数允许传入0个或任意个含参数名的参数,这些参数在函数内部自动组装为一个dict,形式为**参数名

关键字参数可以拓展函数的功能,如下所示:

1
2
3
4
5
6
7
8
9
def person(name,age,**kw):
print('name:',name,'age:',age,'other:',kw)
person('Lisi',34)
person('Zhangsan',44,city='Shanghai')
person('Wangwu',23,gender='M',job='teacher')
#运行结果如下
name: Lisi age: 34 other: {}
name: Zhangsan age: 44 other: {'city': 'Shanghai'}
name: Wangwu age: 23 other: {'gender': 'M', 'job': 'teacher'}

将dict元素变成可变参数传进函数中,可写成:

1
2
3
4
5
6
def person(name,age,**kw):
print('name:',name,'age:',age,'other:',kw)
extra={'city':'Shanghai','job':'teacher'}
person('Wangwu',23,**extra)
#运行结果如下
name: Wangwu age: 23 other: {'city': 'Shanghai', 'job': 'teacher'}

命名关键字参数

若要限制关键字参数名字,只接收特定的参数可以用命名关键字参数,形式为*,限制参数名。命名关键字参数可以设置默认值,调用函数时必须传入参数名

函数定义如下,则表示只接收city和job作为关键字参数:

1
2
def person(name,age,*,city,job):
print(name,age,city,job)

若函数定义中已经有一个可变参数,后面跟着的命名关键字参数就不需要特殊分隔符*

1
2
def person(name,age,*args,city,job):
print(name,age,args,city,job)

参数组合

定义函数可以使用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,5种参数之间可以组合使用,但参数定义的顺序必须为:必选参数、默认参数、可变参数、命名关键字参数关键字参数

1
2
3
4
def f1(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
def f2(a, b, c=0, *, d, **kw):
print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)

练习题

以下函数允许计算两个数的乘积,请稍加改造,变成可接收一个或多个数并计算乘积:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# -*- coding: utf-8 -*-
def mul(x, *y):
for i in y:
x=i*x
return x

# 测试
print('mul(5) =', mul(5))
print('mul(5, 6) =', mul(5, 6))
print('mul(5, 6, 7) =', mul(5, 6, 7))
print('mul(5, 6, 7, 9) =', mul(5, 6, 7, 9))
if mul(5) != 5:
print('测试失败!')
elif mul(5, 6) != 30:
print('测试失败!')
elif mul(5, 6, 7) != 210:
print('测试失败!')
elif mul(5, 6, 7, 9) != 1890:
print('测试失败!')
else:
try:
mul()
print('测试失败!')
except TypeError:
print('测试成功!')
#运行结果如下
mul(5) = 5
mul(5, 6) = 30
mul(5, 6, 7) = 210
mul(5, 6, 7, 9) = 1890
测试成功!

递归函数

递归函数优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出

练习题

汉诺塔的移动可以用递归函数非常简单地实现。

请编写move(n, a, b, c)函数,它接收参数n,表示3个柱子A、B、C中第1个柱子A的盘子数量,然后打印出把所有盘子从A借助B移动到C的方法。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 期待输出:
# A --> C
# A --> B
# C --> B
# A --> C
# B --> A
# B --> C
# A --> C
# -*- coding: utf-8 -*-
import math
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 --> B
C --> B
A --> C
B --> A
B --> C
A --> C
CATALOG
  1. 1. 函数
    1. 1.1. python内置函数
      1. 1.1.1. 练习题
    2. 1.2. 定义函数
    3. 1.3. 空函数
    4. 1.4. 参数检查
    5. 1.5. 函数返回
      1. 1.5.1. 练习题
    6. 1.6. 默认参数
    7. 1.7. 可变参数
    8. 1.8. 关键字参数
    9. 1.9. 命名关键字参数
    10. 1.10. 参数组合
      1. 1.10.1. 练习题
    11. 1.11. 递归函数
      1. 1.11.1. 练习题