Python初学小知识(九):函数


C语言和Python经常弄混,尤其总是忍不住给Python后面加分号……干脆给自己做个笔记省的忘了。。。(在慕课网学习的)

十三、函数

1. 简介

使用函数,把重复的逻辑代码封装起来,我们把封装重复逻辑代码的过程就做抽象,抽象是数学中非常常见的概念。在这个文档里面,列举了Python内置的大部分函数
传递的参数数量、类型一定要和函数要求的一致,不然将会引起错误。

sum()函数接收一个list作为参数,并返回list所有元素之和。请计算 1×1 + 2×2 + 3×3 + … + 100×100。

L = []
x = 1
while x <= 100:
    L.append(x * x)
    x = x + 1

print(sum(L))

>>> 338350

2. 定义函数

2.1 def()

定义一个函数要使用 def 语句,依次写出函数名、括号()、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用 return 语句返回。

#定义一个求绝对值的函数
def my_abs(x):
	if x >= 0:
		return x
	else:
		return -x

my_abs(-3)
>>> 3

2.2 return()

2.2.1 返回一个值

return表示返回的意思,函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。

#定义一个求列表list所有元素的和的函数
def list_sum(L):
    result = 0
    for num in L:
        result = result + num
    return result
2.2.2 返回None

如果在函数内把结果打印出来,不通过return返回结果:

#定义一个求列表list所有元素的和的函数
def list_sum(L):
    result = 0
    for num in L:
        result = result + num
    print('result is {}'.format(result))
    return

L = [1, 3, 5, 7, 9, 11]
result =list_sum(L) #调用定义的sum_list函数并获得return返回的结果
print(result)

>>> result is 36
	   None

在print(result)中,我们得到None的结果,这是合理的,因为在函数内部,我们把结果打印出来了,但是没有把结果返回。

2.2.2 返回多个值

函数也可以返回多个值,多个值之间使用逗号分隔即可,但是需要注意顺序。

def data_of_square(side):
    C = 4 * side
    S = side * side
    return C, S

C, S = data_of_square(16)
print('周长 = {}'.format(C)) # ==> 周长 = 64
print('面积 = {}'.format(S)) # ==> 面积 = 256

#也可以使用一个值存储函数返回的多值结果:
result = data_of_square(16)
print(result) # ==> (64, 256)

#打印的result,其实是tuple类型,如果我们需要取出结果中的周长或者面积,使用对应位置的下标即可:
print(result[0]) # ==> 64
print(result[1]) # ==> 256

3. 递归函数

在函数内部,还可以调用其他函数,通过合理拆分逻辑,可以降低程序的复杂度。如果在一个函数内部调用其自身,这个函数就是递归函数。

计算阶乘 n! = 1 * 2 * 3 * … * n

'''可以看出:fact(n) = n! = 1 * 2 * 3 * ... * (n-1) * n = (n-1)! * n = fact(n-1) * n
所以,fact(n)可以表示为 n * fact(n-1),只有n=1时需要特殊处理。'''
def fact(n):
    if n == 1:
        return 1
    return n * fact(n - 1)

print(fact(1)) # ==> 1
print(fact(5)) # ==> 120

我们可以拆解fact(5)计算的详细逻辑:

===> fact(5)
===> 5 * fact(4)
===> 5 * (4 * fact(3))
===> 5 * (4 * (3 * fact(2)))
===> 5 * (4 * (3 * (2 * fact(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120

递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
使用递归函数需要注意防止栈溢出:

>>> print(fact(10000))

Traceback (most recent call last):
  File "index.py", line 8, in 
    print(fact(10000))
  File "index.py", line 6, in fact
    return n * fact(n-1)
  File "index.py", line 6, in fact
    return n * fact(n-1)
  File "index.py", line 6, in fact
    return n * fact(n-1)
  File "index.py", line 6, in fact
    return n * fact(n-1)
  File "index.py", line 6, in fact
    return n * fact(n-1)
    ......

4. 函数使用参数

函数参数可以是任意的数据类型,只要函数内部逻辑可以处理即可。
isinstance()函数可以判断参数类型,它接收两个参数,第一个是需要判断的参数,第二个是类型。

>>> isinstance('abcd', str)
True
>>> isinstance(100.0, int)
False
>>> isinstance((1,2), tuple)
True
>>> isinstance({'A':1, 'B':2}, dict)
True
>>> isinstance([1,2], str)
False
>>> isinstance([1,2], list)
True

利用isinstance()函数可以优化函数,比如:

def my_abs(x):
    if not isinstance(x, int) or not isinstance(x, float):
        print('param type error.')
        return None
    if x >= 0:
        return x
    else:
        return -x

5. 函数使用默认参数

默认参数的意思是当这个参数没有传递的时候,参数就使用定义时的默认值。
例如Python自带的 int() 函数,其实就有两个参数,我们既可以传一个参数,又可以传两个参数:

#int(value, [base=10]),base表示value的进制,int()返回十进制
>>> int('12')  #默认base=10
12
>>> int('12', 8)  #12是八进制,返回十进制是10
10
>>> int('12', 16)
18

函数的默认参数的作用是简化调用,我们只需要把必须的参数传进去。但是在需要的时候,又可以传入额外的参数来覆盖默认参数值:

#定义一个计算 x 的N次方的函数:
def power(x, n):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x  # n=1,2时满足while条件,所以s乘了两次x
    return s
        
print(power(5, 2))  # ==> 25

假设计算平方的次数最多,我们就可以把 n 的默认值设定为 2:

def power(x, n=2):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

power(5) # ==> 25

由于函数的参数按从左到右的顺序匹配,所以默认参数只能定义在必需参数的后面,否则将会出现错误,如:def power(n=2, x)

6. 函数使用可变参数

Python函数还接收一种参数叫做可变参数,可变参数即任意个参数的意思,可变参数通常使用*args来表示:

def func(*args):
    print('args length = {}, args = {}'.format(len(args), args))

func('a')
func('a', 'b')
func('a', 'b', 'c')

#结果:
args length = 1, args = ('a',)
args length = 2, args = ('a', 'b')
args length = 3, args = ('a', 'b', 'c')

Python会把可变参数定义为一个tuple,所以在函数内部,可以把可变参数当作tuple来使用。
定义可变参数的目的也是为了简化调用。假设我们要计算任意个数的平均值,就可以定义一个可变参数:

def average(*args):
    sum = 0
    for item in args:
        sum += item
    return sum / len(args)

print(average(1,2,3,4))  # ⇒ 2.5

7. 函数使用可变关键字参数

Python的参数是看作元组的,只能通过索引去寻找,如果顺序发生变化得时候,下标就会失效,函数逻辑就得重新修改实现。
与字典类似,Python函数提供可变关键字参数,可以通过关键字的名字key找到对应的参数值。

def info(**kwargs):
    print('name: {}, gender: {}, age: {}'.format(kwargs.get('name'), kwargs.get('gender'), kwargs.get('age')))

info(name = 'Alice', gender = 'girl', age = 16)
#结果是:name: Alice, gender: girl, age: 16

对于一个拥有必需参数,默认参数,可变参数,可变关键字参数的函数,定义顺序是这样的:

def func(param1, param2, param3 = None, *args, **kwargs):
    print(param1)
    print(param2)
    print(param3)
    print(args)
    print(kwargs)

func(100, 200, 300, 400, 500, name = 'Alice', score = 100)
# ==> 100
# ==> 200
# ==> 300
# ==> (400, 500)
# ==> {'name': 'Alice', 'score': 100}

在这里插入图片描述

编写一个函数,它接受关键字参数names,gender,age三个list,分别包含同学的名字、性别和年龄,请分别把每个同学的名字、性别和年龄打印出来。

def info(**kwargs):
    names = kwargs['names']
    gender_list = kwargs['gender']
    age_list = kwargs['age']
    index = 0
    for name in names:
        gender = gender_list[index]
        age = age_list[index]
        print('name: {}, gender: {}, age: {}'.format(name, gender, age))
        index += 1

info(names = ['Alice', 'Bob', 'Candy'], gender = ['girl', 'boy', 'girl'], age = [16, 17, 15])

#结果是:
name: Alice, gender: girl, age: 16
name: Bob, gender: boy, age: 17
name: Candy, gender: girl, age: 15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值