2019-05-18第四次课

变长参数

'*形参'将参数都放置在一个元组中

def self_print(name,*a):
    print(name)
    print(a)
    print(type(a))

self_print('number',1,2,3,4,5,6,7,8,9)

'**形参'将参数都放置在一个元组中

def self_print(**a):
    print(a)

self_print(first_name = '景涛',last_name = '于')

混合使用时,参数的顺序:位置参数->元组->字典

def mix(a,*b,**c):
    print(a)
    print(b)
    print(c)
#调用时,也要严格遵循参数的顺序
mix('name','age','id',sex = 'male')
  • 拆包
t= (1,2,3,4,5)
print(*t)

def f(tt):
    print(*tt)

f(t)

def ff(**kwargs):
    print(kwargs)

{'name':'zhangsan','age':20}

ff(**{'name':'zhangsan','age':20})

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)

print('总和为%f' % sum)
print('平均值为%f' % avg)
  • 函数的传参问题
  1. 数据分为引用类型和普通类型;
  2. python 中的基本数据类型都是普通类型,数,布尔型,字符串型也都是普通类型;
  3. 除了以上类型,都是引用类型;
  4. 普通类型赋值的时候,传的是值;
  5. 引用数据类型赋值的时候,传的是地址;
#引用类型赋值
l1 = [1,2,3,4,5]
l2 = l1

l2[1] = 5
print(l1)

#普通类型赋值
a = 5
b = a
b = 10
print(a)

  • 一个便于深度理解代码在内存中运行的网站

http://www.pythontutor.com/visualize.html#mode=edit

传参的本质就是赋值操作,如果传递的是引用数据变量,则需要注意是否在函数中对其做出了修改

def power(numbers):
    #利用解析式则另开辟了一个表
    #numbers = [x**2 for x in numbers]
    #创建一个副本(法一)
    #numbers = number[:]
    #创建一个副本(法二)
    numbers  =list(numbers)
    #对副本进行修改,则不改变原表
    numbers[3]  = 10
    return numbers

nums = [1,2,3,4,5,6,7,8,9]
print(power(nums))
print(nums)

闭包(嵌套)

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

def fun():
    print('hello,world!')

f = fun
f()
  • 函数的嵌套(闭包)
  1. 内层函数可以访问外层函数的变量,但是不能修改;
  2. 内层函数访问变量时,会先从自己内部查找,如果找不到,就会层层向上查找;
  3. python中,变量的作用域是以函数为单位的;
  4. global修饰变量时,说明使用的是最外层的全局变量;
  5. nonlocal修饰变量时,说明使用的嵌套层函数的变量;
  6. 闭包的本质是函数嵌套函数,外层函数返回内层函数的地址;
a = 11
def outter():
    a = 10

    def inner():
        #这个a为另开辟的一个新变量
        a = 20
        #下面两个方法使用最外层和外层的a
        #通过以下方法声明a为全局变量,则可以对最外层的a进行修改
        # global a
        # a -= 1
        #通过以下取消外层a的局部特性,可以在内层修改外层的a了
        #nonlocal a
        # a -= 1
        print(a)
        print('hello,inner.')
    print(a)

    return inner

fo = outter()
fo()

递归

函数自己调用自己,编写递归或循环,一般先考虑出口(结束的条件)问题。

  • 阶乘
#5!
#普通方法
def factorial(n):
    mm = 1
    for num in range(1,n+1):
        mm *= num
    return mm

print(factorial(5))

#递归方法
def factorial(n):
    if n == 1:
        return 1
    return n*factorial(n-1)

print(factorial(5))

#效率差不多,优先可读性
  • 斐波那契数列
#用循环实现
def fibonacci(n):
    before = 0
    after = 1
    if n == 1:
        return 1

    for i in range(2,n+1):
        tmp = before + after
        #before = after
        #after = tmp
        before,after = after,tmp

    return tmp
for i in range(1,11):
    print(fibonacci(i))

#用递归方法实现
def fbnq(n):

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

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

高阶函数

函数的参数或函数的返回值是函数的函数

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,5))

print(handle(my_sum,1,2,3,4,5,6))
  • 系统中带的高阶函数

map(func,inteable)
该函数会把inteable中的数据依次传递给func函数处理,最后把处理的结果返回

#eg:[1,2,3,4,5] -->[1,4,9,16,25]
def power(x):
    return x*x

result = map(power,[1,2,3,4,5])

#上述函数用匿名函数实现一下:
# result = map(lambda x:x*x,[1,2,3,4,5])

#result中的结果是个生成器
# for i in result:
#     print(i)

print(list(result))

reduce(func,inteable)
累计操作:func为一个接收两个参数的函数,func将多次执行,第一次执行则向inteable中读取两个数据;随后的运算中,第一个参数为上一次func函数return的结果,第二的参数为inteable中的下一个数据。

from functools import reduce
li = [1,2,3,4,5]
result = reduce(lambda x,y:x*y,li)
print(result)

filter(func,interable)
过滤:根据函数func来过滤interable;将interable中的数据传入函数func中,如果函数返回true,就保留该数据,否则就不保留。

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

sorted(interable,key = None,reverse = False)
对数据进行排序,key可以用来指定排序的规则,值是一个函数,reverse是来指定排序的顺序-->升序或降序

li.sort()为就地排序,就地排序会影响原始数据,而sorted不会影响原始数据
 li = [-12,13,56,-23,2,-55]
 rs = sorted(li,key= abs, reverse=True)
 print(rs)
 print(li)

模块

#food4.py
def make_pizza():
    """

    :return:
    """
    print("制作披萨完成")

def make_bun():
    """

    :return:
    """
    print("制作馒头完成")

#test4.3.py
from food4 import make_pizza
make_pizza()
#如果有重名函数,则可以:
#from pizza import make_pizza as mp
#mp()
import food4
 food4.make_bun()

模块就是一个文件,我们在编写程序的时候,可以把功能相似的代码放在一个模板中。
导入模板方式:1,from 开头: from模板名 import 开头
2,import 开头: import 模板名
可以使用as为模板或函数起一个别名:
from pizza import make_pizza as mp

函数的注释

 def ff():
     """
     打印test!!
     :return:
     """
     print("test!!")
 
 print(ff.__doc__)
 
 help(ff)

关于元组内容不可变的一个误区

如t = (1,2,3,[1,2,3],4)中的列表只存放了它的地址,因此只有它的地址不可变,而内容是允许改变的

你可能感兴趣的:(2019-05-18第四次课)