2019-05-20

python之函数

先通过一个简单的例子来了解一下函数的概念:

定义一个累和函数caculatenum

def caculateNum(Num):
   res = 0
   for i in range(1,Num+1):
       res += i
   return res

res = caculateNum(100)
print(res)#5050

返回值return也可以直接用来定义函数,比如

def caculateNum(Num):
  return sum([i for i in range(1,Num+1)])
res = caculateNum(100)
print(res)#5050

一,必须参数和关键字参数
1.必须参数
必须参数必须以正确的顺序传入,调用的时候必须和声明的时候保持一致
如:

def f(name, age):
    print('I am %s , I am %d years old'%(name,age))
f(18,'wxn')#报错

之所以会报错是因为18,wxn没有与定义参数时的必须参数类型相对应
这里就涉及到格式化输出的问题了,%s代表字符串,%d代表十进制整数
2.关键字参数
关键字参数,使用关键字参数可以允许函数调用时和声明时顺序不一致
,python 解释器能够用参数名字匹配参数值
如:

def f(name, age):
    print('I am %s , I am %d years old'%(name,age))
f(age=18,name='verg')#I am verg , I am 18 years old

这里就用到了age和name这两个关键词
二,默认参数
默认参数 缺省参数没有传入,默认值会生效

def f(name,age,sex = 'male'):
    print('I am %s , I am %d years old' % (name, age))
#I am lisi , I am 19 years old
#sex : male
    print('sex : %s'%sex)
#I am 张三 , I am 88 years old
#sex : famale
f(name='lisi',age=19)
f('张三',88,'famale')

三,匿名函数

lambda 参数:表达式

冒号前面是参数,可以有多个,后面是表达式,只能是一个表达式

不写return,返回值就是表达式的结果
减少代码量,代码看起来有逼格

res = lambda  x , y :x*y
print(res(4,5))#20
store = []
s = "淘宝"if len(store)==0 else store[0]

即如果if后面的条件满足则返回if前的的内容
否则返回store列表的第一个数值即store[0]

print(s)#淘宝 

说明条件满足

下面通过举例说明lambda函数的方便之处

def cal(x,y):
    if x>y:
        return  x*y
    else:
        return  x/y
print(cal(3,4))#0.75

使用lambda函数:

calc = lambda x,y:x*y if x>y else x/y
print(calc(2,3))#0.666666

冒号前面是参数,后面是表达式,而且不需要返回值return,非常方便了

用sorted(列表名,key=lambda 参数:元素)的方法直接给列表排序

stus = [
    {'name':'ae','age':1,},
    {'name':'ga','age':2,},
     {'name':'pa','age':4,},
      {'name':'ba','age':9,},
       {'name':'va','age':5}
]
#key值是按照哪个元素为依据进行排序

res = sorted(stus,key=lambda x:x['age'])#取age的值进行排序
print(res)
res = sorted(stus,key=lambda x:x['name'])#根据名字的首字母顺序进行排序
print(res)

四,两种传参方式
按位置传参与按关键词传参

def get_fullname(last_name,first_name):
 full_name = last_name + first_name
    return full_name
full_name = get_fullname('wang','xinnan')
full_name = get_fullname(first_name= 'xinnan',last_name='wang')
print(full_name)

这里需要注意按关键词传参的时候有默认值的要放在最后面

五,变长参数

*的作用:1.将参数打包成元组

def self_print(*a):#用*将参数都放置到一个元组中
    print(a)#(1, 2, 3, 4, 5, 6)
    print(type(a))#<class 'tuple'>元组,元组参数不可改变
self_print(1,2,3,4,5,6)
def self_print(name,*a):
    print(a)#(2, 3, 4, 5, 6)
    print(name)#1

self_print(1,2,3,4,5,6)

这里self_print的第一个数值1传给了参数name,剩下的2,3,4,5,6在的打包下都传给了a
2.如果参数本身就是一个元组或者列表,
能在输出的时候将它拆开
如:

t = (1,2,3,4,5)
print(*t)#1 2 3 4 5  没有括号
def f(*tt):
    print(tt)#(1, 2, 3, 4, 5)
f(*[1,2,3,4,5])

**的作用:1.将参数都放到字典中,注意这个参数必须有关键字

def d_self_print(**kwargs):
    print(kwargs)

d_self_print(last_name = "wang",frist_name = "xinnan")#{'last_name': 'wang', 'frist_name': 'xinnan'}

形参顺序:位置参数->元组->字典

def mix(name,*t,**kwargs):#kwargs是关键字参数的意思
    print(name)#wangxinnan
    print(t)#('20', 'dongqin')
    print(kwargs)#{'gender': '鲁班'}

mix('wangxinnan','20','dongqin',gender = '鲁班')#带关键词的应该放在最后

return 返回值

def sum_and_avg(*numbers):
    total = sum(numbers)
    avg_number = total/len(numbers)
    return total,avg_number

sum,avg = sum_and_avg(1,2,3,4,5,6,7,8,9,10)
print("总和是%f"% sum)#总和是55.000000
print("平均值是%f"%avg)#平均值是5.500000

函数的传參问题

1.数据分为引用类型和普通类型
python中的基本数据类型都是普通类型,数,布尔型,字符串型
除了这些以外的类型都是引用类型
普通类型赋值的时候,传的是值,引用类型赋值的时候传的是地址

举个例子

l1 = [1,2,3,4,5]
l2 = l1
l2[1] = 5
print(l1)#[1, 5, 3, 4, 5] 

这里的l1中的参数属于引用类型,所以l1 l2共用同一个地址,所以在更改了l2中的第二个数据后l1中的也会一起更改,所以传參的本质就是赋值操作,如果传递的是引用类型数据,则需要注意是否在函数中对其做出了修改

def power(numbers):
    numbers  = [x**2 for x in numbers]
    return numbers
nums = [1,2,3,4,5,6,7]
print(power(nums))#[1, 4, 9, 16, 25, 36, 49]
print(nums)#[1, 2, 3, 4, 5, 6, 7]

这里的参数属于普通类型,所以原本的nums不会一起改变

def power(numbers):
     numbers = list(numbers)
     numbers[3] = 10
     return numbers
nums = [1,2,3,4,5,6,7,8]
print(power(nums))#[1, 2, 3, 10, 5, 6, 7, 8]成功将第四个数换成了10

函数名的本质是函数的地址

def fun():
    print("hello world")
f = fun
f()

用f()可直接执行函数fun()

闭包

内层函数可以访问外层函数的值,但是不能修改
内层函数访问变量时会先从自己内部查找,如果找不到就会层层向上查找

def outter():
    def inner():
        print("hello innner")

    return  inner
fo = outter()
fo()

闭包的本质是函数的嵌套函数,外层函数返回内层函数的地址

def outter():
    aa= 10
    def inner():#说明使用的是全局变量,最外层
        nonlocal aa
        aa -= 1
        print(aa)
    print(aa)
    return inner
fo = outter()
fo()#9
fo()#8
fo()#7
fo()#6
outter()

nonlocal:让外层的关键字在这一层生效

递归:

函数自己调用自己,编写递归或循环时,一般先考虑出口(结束的条件)问题、
举个例子:阶乘

def factorial(n):
    mm = 1
    for num in range(1,n+1):
        mm*=num
    return mm
print(factorial(5))#120

def factor(n):
    if n==1:
        return 1
    return n*factor(n-1)#是1就返回1,否则返回n*n-1
print(factor(5))#120

高阶函数

def handle(func,*param):
    return func(*param)

def my_sum(*param):
    sum = 0
    for i in range(len(param)):
        sum += param[i]
    return sum
print(my_sum(1,2,3,4,6))#16

def my_mul(*param):
    mul = 1
    for v in param:
        mul *=v

    return mul

print(handle(my_mul,1,2,3,4,5))#120

func代表函数,param代表参数

常见的高阶函数

1.map
map(func,inteable)该函数会把inteable中的数据一次传递给func函数处理,最后把结果返回
inteable是指可迭代对象,可以是一个数组
[1,2,3,4,5]-->[1,4,9,16,25]

def power(x):
    return x*x
result = map(power,[1,2,3,4,5,6])
for i in result:
    #print(i)
print(list(result))#[1, 4, 9, 16, 25, 36]
results = map(lambda x:x*x,[1,2,3,4,5,6,7])
print(list(results))#[1, 4, 9, 16, 25, 36]

2.reduce
reduce(func,inteable)函数:累计操作,fun函数必须接收两个参数,reduce会把func的运行结果当做一个参数

from functools import reduce

l = [1,2,3,4,5]
result1 =reduce(lambda x,y:x*y,l)
print(result1)#120

3.filter
filter(func,inteable)过滤:根据函数func来过滤interable

l1 = [1,2,3,4,5,6,7,9,34]
result = list(filter(lambda x:x%2 == 1 ,l1))
print(result)#[1, 3, 5, 7, 9]

将interable中的数据传入func中,如果函数返回true,就保留该数,不然就删去

斐波那契数列

方法一:递归法

def fbnq(n):
    if n == 1 or n == 2:
        return 1
    return fbnq(n - 1) + fbnq(n - 2)


for i in range(1, 10):
    print(fbnq(i))

2.for循环的方法

def fbnq(n):
    a = 0
    b = 1
    if n ==1:
        return 1

    for i in range(2,n+1):
        tmp = a + b
        a ,b =b,tmp
    return tmp
for i in range(1,10):
    print(fbnq(i))
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容