第七课:函数

第七课:函数

定义:函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段
.语法:
def 函数名(参数列表):
 函数体
 return XXX
可以返回多个值,返回的多个值组成一个元组,返回值加上一对中括号,则返回一个列表
函数分为定义和调用

1>无参函数
函数无参方法
 def wu():
     print("我爱你!");
 wu();#调用方法

2>有参方法
def wwu(str):
    print(str)
wwu("love you");

#练习:定义一个函数,实现两个数字的加、减、乘、除
#无参方法
def suanshi():
    a=2;
    b=3;
    print("加法:"+str(a+b));
    print("减法:"+str(a-b));
    print("乘法:"+str(a*b));
    print("除法:"+str(a/b));
suanshi();

#有参
#定义一个函数,实现两个数字的加、减、乘、除
def yunsuan(num1,num2):
    print(num1+num2);
    print(num1-num2);
    print(num1*num2);
    print(num1/num2);
yunsuan(4,2);

#有参方法的返回值
def yun(a,b):
    print("函数内部:",a+b);
    return a+b;
re=yun(3,5);
print("返回值:",re);

3.可更改(mutable)与不可更改(immutable)对象
在 python 中,strings(字符串), tuples(元组), 和 numbers(数字) 是不可更改的对象,而 list(列表),dict(字典) 等则是可以修改的对象。
不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了

3-1>
用值传递传递方式(复制内存地址的副本)去传递 可变类型-可改变内容 不可改变原地址
引用传递:值传递的类型是 可变数据类型
可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
示例:
ff=['悟空','八戒','沙僧'];
def fun(nums):
    nums[0]="张飞";
    nums[1]="刘备";
    nums=ff;

nums=["李逵","松江"];
# print("调用前:",nums)
fun(nums)
print("调用后:",nums)

3-2>
不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。
比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
示例:
def fun(a1):
    a1="李四";
    print("函数内部a1:",a1)

a="张三";
print("调用前:",a)

fun(a)#调用后
print("调用后:",a)

4>
以下是调用函数时可使用的正式参数类型:
函数下第一个''' 文档内容 doc  函数名.__doc__
def fun1(a=3,b=2):
    '''
    :param a 第一个加数:
    :param b:第二个加数
    :return: a+b的和
    '''
    return  a+b;
h=fun1(4,4);
print(h)
#传参
 def printinfo( name, age = 35 ):#默认参数
  "打印任何传入的字符串"
  print ("名字: ", name);
  print ("年龄: ", age);
  return;

 printinfo('ok');#传入'name'参数
4-1>
 不定长参数(可变参数):
 可变参数允许你传入0个或任意个参数,
 这些可变参数在函数调用时自动组装为一个tuple
 def GetSum(*nums):
     sum=0;
     for i in nums:
         sum+=i;
     return sum;

 s=[2,3,4,5];
 t=(2,3,4,5,6,7,8)
 print(GetSum())
 print(GetSum(*s))
 print(GetSum(*t))

4-2>
 关键字参数:关键字参数允许你传入0个或任意个含参数名的参数,
 这些关键字参数在函数内部自动组装为一个dict
 例:# 关键字参数:**kw
 def student(name,age,**kw):
     kw.clear()
     print('姓名{} ,年龄{} other:{}'.format(name,age,kw))

 #值传递
 def fun3(kw):
     kw.clear();

 student('tom',30,hao='篮球',ai='足球');
 dic={'一':123,'二':223,'三':333}
 student('ok',30,**dic)
 print(dic)

 dic2={'一':123,'二':223,'三':333}
 fun3(dic2)
 print(dic2)

4-3>
# 参数组合
# 比如定义一个函数,包含上述若干种参数:
def f1(a, b, c=0, *args, **kw):
  print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

args = (1, 2, 3, 4)
kw = {'d': 99, 'x': '#'}
f1('A','B')
f1(b='B',a='A')
f1(b='B',a='A',c=9)
f1(*args)
f1('A','B',**kw)
f1(*args,**kw)

小结
Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。
默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
要注意定义可变参数和 **kw 关键字参数的语法:
*args是可变参数,args接收的是一个tuple;
**kw是关键字参数,kw接收的是一个dict。

传参数:*args 会逐个分割args 逐个对应形参列表
**kw 只能对应到形参列表的 **kw

变量作用域:
全局变量与局部变量的作用域不同
生命周期不同
全局变量:
g_a=10
def test2():
    global g_a#告诉程序这里是一个全局变量
 g_a=20
    print(g_a)
def test3():
    print(g_a)
test2()
test3()
当全局变量和局部变量同名时,局部变量优先
局部变量

4-4>
匿名函数:
python 使用 lambda 来创建匿名函数
语法:lambda [arg1 [,arg2,.....argn]]:expression
语法:lambda [参数列表]:函数体内部代码

#匿名函数:
# python 使用 lambda 来创建匿名函数

def fun1(a=3,b=2):
    '''
    :param a 第一个加数:
    :param b:第二个加数
    :return: a+b的和
    '''
    return  a+b;

sum=lambda a,b:a*b;
# s=sum(2,3);
# print(s);
def dfdsfe(a,b):
    return a+b;

def add(a,b,fun):
    '''
    :param a:
    :param b:
    :param fun 传递过来的函数:
    :return:
    '''
    print(fun(a,b));

add(11,22,dfdsfe)

foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
fun=lambda x: x%2!=0;
f=filter(fun,foo);

print(list(f))

4-5>
python filter():对于序列中的元素进行筛选,最终获取符合条件的序列
foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
f=filter(lambda x:x%3==0,foo)
print(list(f))

#利用filter(),可以完成很多有用的功能,例如,删除 None 或者空字符串:

def is_not_empty(s):
    return  s and len(s.strip())>0;

names=['ko',None,'','ok'];

l=list(filter(lambda s:s and len(s.strip())>0,names))
print(l)
注意: s.strip(rm) 删除 s 字符串中开头、结尾处的 rm 序列的字符。
当rm为空时,默认删除空白符(包括'\n', '\r', '\t', ' ')
4-7>
foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
#mapmap将序列的每个元素传入函数中执行,并把结果作为新的list返回。
print(list( map(lambda x:x%2,foo)))

# python reduce():对于序列内所有元素进行累计操作
r=reduce(lambda a,b:a+b,foo);
sum =reduce(lambda a,b:a+b, (1, 2, 3, 4, 5, 6, 7))

4-8>
python map()
map()函数接收两个参数,一个是函数,一个是序列,map将序列的每个元素传入函数中执行,并把结果作为新的list返回。
举例说明,比如我们有一个函数f(x)=x%2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现
print map(lambda x: x % 2, range(7))
[0, 1, 0, 1, 0, 1, 0]

5>reduce()函数已经从全局名字里空间移除,它现在被放在fucntools模块里
如果想运用此函数需导入fucntools模块,之后调用reduce()函数,作用:对于序列内所有元素进行累计操作
首先导入:import _functools
第一种方法:
li=[11,22,33,44,55,66];
result=_functools.reduce(lambda a,b:a*b,li)
不会自动返回一个值,需要找一个变量承接
print(result);
小结:reduce内建函数是一个二元操作函数,他用来将一个数据集合(链表,元组等)中的所有数据进行下列操作:
用传给reduce中的函数 func()(必须是一个二元操作函数)先对集合中的第1,2个数据进行操作,
得到的结果再与第三个数据用func()函数运算,最后得到一个结果。
第二种方法:
如:
 def myadd(x,y): 
 return x+y 
 sum=reduce(myadd,(1,2,3,4,5,6,7))#第一个值是调用函数,第二个是列表
 print sum 
也可以用lambda的方法,更为简单:
 sum=reduce(lambda x,y:x+y,(1,2,3,4,5,6,7)) 
 print sum

reduce()函数也是Python内置的一个高阶函数。reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。

例如,编写一个f函数,接收x和y,返回x和y的和:

def f(x, y):
 return x + y
调用 reduce(f, [1, 3, 5, 7, 9])时,reduce函数将做如下计算:

先计算头两个元素:f(1, 3),结果为4;
再把结果和第3个元素计算:f(4, 5),结果为9;
再把结果和第4个元素计算:f(9, 7),结果为16;
再把结果和第5个元素计算:f(16, 9),结果为25;
由于没有更多的元素了,计算结束,返回结果25。
上述计算实际上是对 list 的所有元素求和。虽然Python内置了求和函数sum(),但是,利用reduce()求和也很简单。

reduce()还可以接收第3个可选参数,作为计算的初始值。如果把初始值设为100,计算:
reduce(f, [1, 3, 5, 7, 9], 100)
结果将变为125,因为第一轮计算是:

计算初始值和第一个元素:f(100, 1),结果为101。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值