函数
(1) 传递任意数量的实参: 形参名*args 中的星号让Python创建一个名为args的空元组,并将收到的所有值都封装到这个元组中。 **kwargs 让Python创建一个名为args的空字典(args和kwargs只是名称,可以自定义) 实例: # 使用*args def test_args(*args) for n in args: print(n) args_list = [1,2,3,4] test_args(args_list) #输出为1 2 3 4 # **args的使用 def test_kwargs(**kwargs): for key,val in kwargs: print(key + ' ' + val) test_kwargs(name = 'why',age = '18') # 输出为 name why age 18 (2)range:惰性创建数字列表,默认连续,可指定步长,python2中立即创建 >>> test = input('输入字符串:') 输入字符串:wvwdvwdvwvwevev >>> range(len(test)) range(0, 15) >>> for index in range(len(test)): print(index) 0 1 2 3
1.高阶函数:一个函数既可以接收变量为参数,也可以接受另一个函数作为参数,这种函数称为高阶函数 例如: >>> def add(x,y,f): return f(x)+f(y) >>> add(-5,-6,abs) 11 2.map和reduce函数: map函数接收两个参数一个函数和一个Iterable(可迭代对象), map函数将Iterable中的每一元素作用于接收到的函数中,返回一个Iterator(迭代器) 举例: >>> def f(x): return x**2 >>> print(list(map(f,[1,2,3,4,5,6]))) [1, 4, 9, 16, 25, 36] reduce函数接受两个参数一个函数和一个Iterable,并且这个函数必须接收两个参数, 先将Iterable中的前两个元素,传入function中,返回的值接着与Iterable之后的元素继续当作实参传入function中, 以此类推 举例: """累加列表中的元素""" >>> from functools import reduce >>> def f(x,y): return x+y >>> reduce(f,[1,2,3,4,5,6,7,8,9]) 45 将map函数和reduce函数结合可以写出str转换为int的函数,代码如下 >>> from functools import reduce >>> def syr2num(s): def fn(x,y): return x*10 + y def char2list(s): return {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}[s] return reduce(fn,map(char2list,s)) >>> syr2num('1234') 1234 3.filter函数 filter接收一个函数和一个Iterable,根据函数返回的是True还是False筛选Iterable中的元素 例1: """ 使用埃氏筛法筛选素数 """ def creat_list(): """列出从3开始的奇数""" n = 1 while True: n = n+2 yield n def filter_list(n): """筛选函数""" return lambda x: x%n>0 def su(): yield 2 it = creat_list() while True: n = next(it) yield n it = filter(filter_list(n),it) for n in su(): if n < 100: print(n) else: break 例2: def is_palindrome(n): """筛选回文数""" if n<10: return True elif n>=10: s = str(n) i = int(len(s) / 2) m = 0 while i>=0: if s[i]==s[-(i+1)]: m += 1 i-=1 if m == int(len(s) / 2)+1: return True else: return False output = filter(is_palindrome, range(1, 10000)) print(list(output)) 4.sorted sorted函数是排序函数 >>> sorted([1,6,4,2,5,7,8,6,5,3,5,7,8]) [1, 2, 3, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8] # 默认使用元素对应的ASCLL码进行排序 >>> sorted(['a','c','b','B']) ['B', 'a', 'b', 'c'] # key函数将作用于每一个元素 >>> sorted(['a','c','b','B'],key = str.lower) ['a', 'b', 'B', 'c'] # 倒序排序 >>> sorted(['a','c','b','B'],key = str.lower,reverse = True) ['c', 'b', 'B', 'a'] # 对元组进行排序会返回一个列表,因为元组不可变 >>> sorted(('a','c','b','B')) ['B', 'a', 'b', 'c'] >>> 举例: """ 假设我们用一组 tuple 表示学生名字和成绩: L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)] 请用 sorted()对上述列表分别按名字排序: """ # -*- coding: utf-8 -*- L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)] def by_name(t): return t[0] L2 = sorted(L, key=by_name) print(L2) """ 再按成绩从高到低排序: """ # -*- coding: utf-8 -*- L1 = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)] def by_score(t): return t[1] L2 = sorted(L1,key=by_score) print(L2) 5.返回函数: 一个函数既可以接收一个函数作为参数,也可以返回一个函数 例1: def lazy_add(*args): def add(): sum = 0 for n in args: sum = sum +n return sum return add >>> ff = lazy_add(1,2,3,4,5,6,7,8,9) >>> ff <function lazy_add.<locals>.add at 0x0000012773E4C1E0> >>> ff() 45 返回的函数中包含了局部变量args,可见当一个函数返回一个函数时,函数中定义的局部变量, 也包含在了被返回的函数当中了(即新函数) 需要注意的是返回的新函数并不是立即执行,而是等到调用时才会被执行 例2: >>> def count(): fs = [] for i in range(1,4): def f(): return i*i fs.append(f) return fs >>> f1,f2,f3 = count() >>> f1() 9 >>> f2() 9 >>> f3() 9 上面这个函数并没有得到我们想要的结果,即f1() 输出1,f2() 输出 4,f3() 输出9 这是因为调用函数时返回的新函数并没有被马上执行,而是等到调用新函数时才执行 调用时变量i已经变为3,所以最后的输出均为9,返回闭包时牢记的一点就是: 返回函数不要引用任何循环变量,或者后续会发生变化的变量。 上面这个例子如果必须要使用循环变量,就再增加一个函数将变量绑定 例2: >>> def count(): def f(j): def g(): return j*j return g fs = [] for i in range(1,4): fs.append(f(i)) return fs >>> f1,f2,f3 = count() >>> f1() 1 >>> f2() 4 >>> f3() 9 这样就得到了想要得到的返回结果 6.匿名函数: 格式:lambda 参数: 表达式 相当于: def func(参数): return 表达式 注意匿名函数只能有一个表达式 匿名函数可以当作参数传递给函数,如map函数 例1: list(map(lambda x: x*x,[1,2,3,4,5,6,7,8,9])) >>>[1,4,9,16,25,36,49,64,81] 匿名函数还可以作为一个变量 例2: >>> f = lambda x: x*x >>> f(5) 25 匿名函数还可以当作函数的返回值 例3 >>> def f(): return lambda x: x*x >>> ff = f() >>> ff(5) 25 7.decorator装饰器 #装饰器:本质就是函数,装饰其他函数(为其他函数添加其他功能),不修改被装饰函数的源代码和调用方式 装饰器的作用是在代码运行期间动态的增加功能 我们写一个打印时间的函数: def now(): print('2019-05-29') >>>2019-05-29 如果我们想添加一个函数执行日志,就需要写一个装饰器: def log(func): """"一个打印函数执行日志装饰器""" def f(*args,**kw): print("%s():",func.__name__) return func(*args,**kw) return f 这个装饰器的使用方法是: @log() def now(): print('2019-05-29') >>> now() date,now(): 2019-05-29 上面的使用方法相当于执行了 now = log(now) 这样做会出现一个问题,现在now()函数指向的是装饰器返回的函数,也就是一个新函数, 此时函数名发生了改变 >>> now.__name__ 'f' 函数名变成了f(),要解决这个问题,python中有专门的解决方法 import functools def log(text): def decorate(func): @functools.wraps(func) # 经过装饰的函数,函数名会改变,该行语句使函数名不发生变化 def f(*args,**kw): print('%s,%s():' % (text,func.__name__)) return func(*args,**kw) # 这里直接返回的是函数执行结果,不是返回函数名 return f return decorate @log('date') def now(): print('2019-05-29') now() print(now.__name__) 这时的输出为: """ D:\python37\python.exe E:/资源/python/DOME.C/LIAOXUEFENG2/decorate.py date,now(): 2019-05-29 now """ 8.偏函数 int()函数可以将字符串变量转换为整数,默认情况下按十进制转换 如: int('1234') >>>1234 但也可以传入参数N,即将字符串按N进制转换、 如: >>> int('1234',base = 8) # 将'1234'按八进制转换为十进制的整数 668 但是每次调用时都需要传入参数,非常麻烦,偏函数就可以解决这个问题 import functools int2 = functools.partial(int,base = 2) 这样我们就把int2()函数变成了一个按二进制转化字符串的函数 >>>int2('10101') 21 相当于执行了: def int2(x,base = 2): return int(x,base) 偏函数的作用就是固定函数中的参数,使调用更方便