python--第五章 python字典&&函数

一、字典

1、初识字典

'''
字典(dict)
    - 字典属于一种新的数据结构,称为映射(mapping)
    - 字典的作用和列表类型,都是用来存储对象的容器
    - 列表存储数据的性能很好,但是查询数据的性能很差
    - 在字典中每一个元素都有一个唯一的名字,通过这个名字可以快速查找到指定的元素
    - 在查询元素时,字典的效率是非常快的
    - 在字典中可以保存多个对象,每个对象都会有唯一的名字
        这个唯一的名字,我们称为键(key),通过key可以快速的查找到value
        这个对象,我们称为值(value)
        所以字典,我们可以称为键值对(key:value)结构
'''

# 使用大括号创建字典
d = {}   # 创建一个空字典

# 创建包含数据的字典
# 语法:
#   {key:value,key:value}
# 字典的值可以是任意对象
# 字典的键可以是任意的不可变对象(int,str,bool,tuple...),但是一般都会使用字符串str
# 字典的键不能重复,如果重复的话后面的键会替换前面的键
d = {'name':'孙小姐','age':18,'gender':'女'}
print(d,type(d))

# 需要根据键来获取值
print(d['name'],d['age'],d['gender'])

# 如果使用字典中没有的键会保存 KeyError: 'helle'
print(d['helle'])

2、字典的使用

# 创建字典
# 方法一 使用{}
# 语法: {k1:v1,k2:v2}
# 方法二 使用dict()函数来创建字典
# 每一个参数都是一个键值对,参数名就是键,参数名就是值(这个方式创建字典,key都是字符串)
d = dict(name='孙小姐',age=18,gender='女')
print(d)
# 方法三 也可以将一个包含双值子序列的序列转换为字典
# 双值序列,序列中只有两个值,[1,2] ('a',3) 'ab'
# 子序列,如果序列中的元素也是序列,那么我们称为这个元素为子序列
# [(1,2),(3,5)]
d = dict([('name','孙小姐'),('age',18)])
print(d,type(d))
d= dict(name='孙小姐',age=18,gender='18')

# len() 获取字典中键值对的个数
print(len(d))

# in 检查字典中是否包含指定的键
# not in 检查字典中是否不包含指定的键
print('hello' in d)

# 获取字典中的值,根据键来获取值
# 语法: d[key]
print(d['age'])

# 通过[]来获取值时,如果键不存在,会抛出异常KeyError
# get(key[,default]) 该方法用来根据键来获取字典中的值
#   如果获取的键在字典中不存在,会返回None
#   也可以指定一个默认值,来作为第二个参数,这样获取不到的时候返回默认值
print(d.get('name'))
print(d.get('hello','没有'))

# 修改字典
# d[key] = value 如果key存在则覆盖,不存在则添加
d['name'] = 'sunwukong'   # 修改字典的key-value
d['address'] = 'hangzhou' # 向字典中添加 key-value
print(d)

# update([other])
# 将其他的字典中的key-value添加到当前字典中
# 如果有重复的key,则后边的会替换到当前的
d = {'a':1,'b':2,'c':3}
d2 = {'d':4,'e':5,'f':6,'a':7}
print(d)
print(d2)
d.update(d2)
print(d)
# print(d)
# 删除,可以使用del,来删除字典中的key-value
del d['a']
del d['b']
print(d)

# popitem()
# 随机删除字典中的一个键值对,一般都会删除最后一个键值对
#   删除之后,它会将删除的key-value作为返回值返回
#   返回的时一个元组,元组中有两个元素,第一个元素是删除的key 第二个删除的是value
# 当使用popitem() 删除一个字典,会抛出异常KeyError: 'popitem(): dictionary is empty'
result=d.popitem()
print(result)
# g = {}
# g.popitem()    #KeyError: 'popitem(): dictionary is empty'

# pop(key[,default])
# 根据key删除字典中的key-value
# 会将被删除的value返回
# 如果删除不存在的key会抛出异常
#   如果指定了默认值,再删除不存在的key时,不会报错,而是直接返回默认值
print(d)
result = d.pop('d')
result = d.pop('z','这是默认值')
print(result)

# del d['z'] z不存在,报错
# result = d.popitem()
# result = d.popitem()
# result = d.popitem()
# result = d.popitem()
# clear()用来清空字典
d.clear()
print(d)

# copy()
# 该方法用于对字典进行浅复制
# 复制以后的对象,和原对象是独立,修改一个不会影响另一个
# 注意,浅复制会简单复制对象内部的值,如果值也是一个可变对象,这个可变对象不会被复制
d = {'a':1,'b':2,'c':3}
d2 = d.copy()
# d['d'] = 100

d = {'a':{'name':'孙小姐','age':18},'b':2,'c':3}
d2 = d.copy()
d2['a']['name'] = '猪猪'

print('d =',d,id(d))
print('d2 =',d2,id(d2))


# 遍历字典
# keys() 该方法返回字典的所有的key
#   该方法会返回一个序列,序列中保存有字典的所有键
d = {'name':'孙小姐','age':18,'gender':'女'}

# 通过遍历keys()来获取所有的键
for k in d.keys():
    print(k, d[k])

# items()
# 该方法会返回字典中所有的项
# 它会返回一个序列,序列中包含有双值子序列
# 双值分别是,字典中的key和value
# print(d.items())
for k,v in d.items():
    print(k, '=', v)

二、集合

1、初始集合

'''
集合(set)
    集合和列表非常像
    不同点:
        集合中只能存储不可变对象
        集合中存储的对象是无序的(不是按元素的插入顺序保存)
        集合中不能出现重复的元素
'''
# 创建集合
# 方法一: 使用{}创建
# 集合中不能存储列表
s = {1,20,3,6,1}
print(s,type(s))

# 方法二: 使用set,可以创建一个空集合
t = set()   # 空集合
print(t,type(t))

# 可以通过set()来将序列和字典转换为集合
s = set([1,2,3,5,6,8,3,6,732,3])
print(s)
s = set({'a':1,'b':2,'c':5})    # 使用set将字典转换为集合,只会保留字典中的键
print(s)
# 集合中不能通过索引来操作,如果想通过索引操作,需要把集合先转为列表
print(list(s)[2])

# 集合中也可以通过in和not in
print(s)
print('p' in s)   # 返回False

# 使用len()来获取集合中元素的数量
print(len(s))

# add() 向集合中添加元素
s.add('p')
print(s)

# update() 将一个集合中的元素添加到当前集合中
s2 = set('hello')
s.update(s2)
print(s)
# 也可以传一个序列或字典
s.update((10,23,7,3))
print(s)
s.update({10:'ab',900:'op'})
print(s)

# pop()随机删除一个集合中的元素
res=s.pop()
print(s)
print(res)      # 将随机删除的元素返回出来

# remove() 删除集合中的指定元素
s.remove(900)
print(s)

# cleal()情况集合
# s.clear()
# print(s)

# copy()对集合进行浅复制
print(s,type(s))

2、集合的运算

# 在对集合做运算时,不会影响原来的集合,而是返回一个运算结果
# 创建两个集合
s = {1,2,3,4,5}
s2 = {3,4,5,6,7}

#  & 交集运算
result = s & s2
print('result = ',result)

# | 并集运算
result = s | s2
print('result = ',result)

# - 差集
result = s - s2
print('result = ',result)

# ^ 异或集
result = s ^ s2
print('result = ',result)

# <= 检查一个集合是否是另一个集合子集
# 如果一个集合中的元素全部都在另一个集合中出现,那么a集合就是b集合的子集,b集合是a集合超集
a = {1,2,3}
b = {1,2,3,4}
result = a <= b
print('result = ',result)    # 返回True

result = {1,2,3} <= {1,2,3}
print('result = ',result)

result = {1,2,3,4,5} <= {1,2,3}

# < 检查一个集合是否是另一个集合的真子集
# 如果超集b中包含有子集,并且b中还有a中没有的元素,则b就是a的真超集,a是b的真子集
result = {1,2,3} < {1,2,3}
result = {1,2,3} < {1,2,3,4,5}  # True

# >= 检查一个集合是否是另一个的超集
# > 检查一个集合是否是另一个的真超集
print('result =',result)     # True

三、函数

1、初始函数

'''
函数简介
    - 函数也是一个对象
    - 函数是内存中专门用来存储数据的一块区域
    - 函数可以用来保存一些可执行的代码,并且可以在需要时,对这些语句进行多次调用
    - 创建函数:
        def 函数名([形参1,形参2,...形参n])
            代码块
        - 函数名必须是要符合标识符的规范
            (可以包含字面,数字,下划线,但是不能以数字开头)
    - 函数中保存的代码不会立即执行,需要去调用才能被执行
    - 调用函数
        函数对象()
    - 定义函数一般都是要实现某种功能的
'''


def fn():
   print('This is a function')
   print('hello')

# 打印fn
print(fn,type(fn))

# 调用函数 fn()调用函数
# print是函数对象,print()调用函数
fn()


'''
函数(function)
    函数的定义都是要有功能的

# 函数的参数
    - 在定义函数时,可以在函数名后的()中定义数量不等的形参
        多个形参之间要使用逗号隔开
    - 形参(形式参数),定义参数就是相当于在函数内部声明了变量,但是并不赋值
    - 实参(实际参数)
        - 如果函数定义时,指定了参数,那么在调用函数时也必须传递实参,
            实参将会赋值给对应的形参,简单来说,有几个形参就得传几个实参
'''
def sum():
    print(1+1)
sum()
# 定义一个带参数的函数

def fn2(a,b,c):
    print('a =',a)
    print('b =',b)
    print('a+b = ',a+b)

fn2(1,2,2)
小练习
# 练习1,定义一个函数求任意三个数得乘积
def sum(a,b,c):
    print('a*b*c = ',a*b*c)

sum(4,5,7)

# 练习2,根据不同的用户名显示不同的欢迎信息
# 答案1
def welcome(username):
    print('欢迎',username+'光临')

welcome('孙小姐')

# 答案2
def user(username):
    if username == 'lai':
        print('huanying guike daolai')
    elif username == 'li':
        print('huanying VIP daolao')
    else:
        print('huanying New guke')

user('la')

2、函数参数的传递

# 定义一个函数
# 定义形参,可以为形参指定默认值
# 指定了默认值后,如果用户传递了参数则默认值没有任何作用
#      如果用户没有传递,则默认值就会生效
def fn(a = 5,b=10,c=20):
    print('a = ',a)
    print('b =',b)
    print('c =',c)

fn(2,3)

# 实参的传递方式
# 位置参数
# 位置参数就是将对应位置的实参复制给对应的位置的参数
# 第一个实参赋值给第一个形参,第二个实参赋值给第二个形参。。。
# fn(1,2,3)

# 关键字参数
# 关键字参数,可以不按照形参定义的顺序去传递,而直接根据参数名去传递参数
fn(b=1,c=2,a=3)
print('hello',end='')    # hello 是一个关键字参数,而end是一个位置参数,end是不让它换行
# 位置参数和关键字参数可以混合使用
#   混合使用关键字和位置参数时,必须将位置参数写在前面
        #否则报错 SyntaxError: positional argument follows keyword argument
fn(1,c=30)

3、参数的类型

实参可以是任意的数据类型
'''
参数的类型
'''
# 函数在调用时,解析器不会检查实参的类型
# 实参可以传递任意类型的对象
def fn2(a):
    print('a =',a)
b = 233     # 这里和下面那行填写a或b或其他都一样的结果
fn2(b)
b = 'hello'
fn2(b)

# 但是我们在定义的时候还是需要去检查下参数的类型的
def fn3(a,b):
    print(a+b)
fn3(123,23)
# fn3(123,'23')   #TypeError: unsupported operand type(s) for +: 'int' and 'str'

def fn4(a):
    # 在函数中对形参进行重新赋值,不会影响其他的变量,如下c的值不会变
    # a = 20
    # a 是一个列表时,尝试修改列表中的元素
    # 如果形参执行的是一个对象,当我们通过形参去修改对象时,会影响到所有指向该对象的变量
    a[0] = 30
    print('a =',a,id(a))
c = 10
c = [1,2,3]
# fn4(c)
# print('c =',c)    # 这个时候打印结果是 c = [30, 2, 3]

# 如果想让c不变可以传它的副本
fn4(c.copy())     # 这个时候传的是复制的对象而不是c本身
print('c = ',c,id(c))

# 或者传递c的c[:]  相对列表
fn4(c[:])
print('c = ',c,id(c))

fn4(c)
print('c = ',c,id(c))    # 这个时候打印结果是 c = [30, 2, 3]

4、不定长的参数(装包,解包)

'''
不定长的参数

'''
# 定义一个函数,可以求任意个数字的和
def sum(a,b,c):
    print(a + b + c)

sum(123,4,5)

# 在定义函数时,可以在形参前面添加一个* ,这样这个参数会获取到所有的实参
# 它将会将所有的实参保存到一个元组中
# 装包  # *a会接受所有的位置实参,并且会将这些实参统一保存到一个元组中
def sum(*nums):
    print("nums =",nums,type(nums))
    result = 0
    # 遍历元组,并将元组中的数进行累加
    for n in nums:
        result += n
    print(result)
sum(1,2,4,6)

# 带*号的参数只能写一个
# 带*号的参数,可以和其他参数配合使用
def fn2(a,b,*c):
    print('a =',a)
    print('b =',b)
    print('c =',c)
fn2(1,2,3,4)

# 可变参数不是必须要写在最后的,但是注意,带*号的参数后的所有参数,必须以关键字参数形式参数,如下需要告诉c=4
# 同理 *a的话也要指定c和b的值是多少
def fn2(a,*b,c):
    print('a =',a)
    print('b =',b)
    print('c =',c)
fn2(1,2,3,c=4)

# 如果在形参的开头直接写一个* ,则要求所有的形参必须要以关键字参数传递
print('-----------------------')
def fn5(*,a,b,c):
    print('a =',a)
    print('b =',b)
    print('c =',c)
fn5(a=2,b=3,c=4)

# *号形参只能接收位置参数,不能接收关键字参数,我们需要用**参数去接收
# 字典的key就是参数的名字,字典的value就是参数值
# **参数只能有一个,并且必须写在所有参数的最后
print('-----------')
def fn3(b,c,**a):
    print('a =',a,type(a))
    print('b=',b)
    print('c=',c)
fn3(b=1,d=2,c=4)


# 参数的解包
def fn4(a,b,c):
    print('a =',a)
    print('b =',b)
    print('c =',c)

# 创建一个元组
t = (10,20,30)

# 传递实参时,也可以在序列类型的参数前添加星号,这样他自动将序列中的元素依次作为参数传递
# 这里要求序列中元素的个数必须和形参的个数一致
print('--------------')
fn4(*t)

# 创建一个字典
d = {'a':100,'b':200,'c':300}
# 通过 **来对一个字典进行解包操作
fn4(**d)

5、函数的返回值 return

# 返回值,返回值就是函数执行后返回的结果
# 可以通过,return来指定函数的返回值
# 可以之间使用函数的返回值,也可以通过一个变量来接收函数的返回值

def sum(*sums):
    # 定义一个变量,来保存结果
    result = 0
    for n in sums:
        result += n
    print(result)
sum(12,3,4)

# return 后边跟什么值,函数就会返回什么值
# return 后边可以跟任意的对象,返回值甚至可以是一个函数

def fn():
    # return 100   # return 后边跟什么值,返回的就是什么
    return [1,2,3]
r = fn()
print(r)

print('------------')
def fn():
    def fn2():
        print('hello')
    return fn2   # 返回值也可以是一个函数
r = fn()
r()    # 返回的就是hello

# 如果仅仅写一个return,或者不写return ,则相当于 return None
def fn2():
    a = 10
r = fn2()
print(r)

# 在函数中,return后的代码都不会执行
def fn3():
    print('heloo')
    return
    print('has')
r = fn3()
print(r)

#
print('-------------')
def fn4():
    for i in range(5):
        if i == 3:
           # break  用来退出当前循环
        # continue  用来跳过当次循环
         return   # 用来结束函数
        print(i)
    print('循环执行完毕')
fn4()

def sum(*sums):
    # 定义一个变量,来保存结果
    result = 0
    for n in sums:
        result += n
    return result
r=sum(12,3,4)
print(r + 20)


def fn5():
    return 20
# fn5 和fn5()的区别
print(fn5)   # fn5是函数对象,打印fn5实际上是打印函数对象 结果 <function fn5 at 0x000001EB13DAC1E0>
print(fn5()) # fn5()是调用函数,打印fn5()实际上是打印的是fn5函数的返回值 20

6、文档字符串

'''
文档字符串
    help()是python中的内置函数
    通过help()函数可以查询python中的函数的用法
    语法:help(函数对象)
    help(print)  # 获取print()函数的使用说明
'''
def fn(a,b,c):
    return 20
help(fn)

# 文档字符串(doc str)
# 在定义函数时,可以在函数内部编写文档字符串,文档字符串就是函数的说明
# 当我们编写了文档字符串时,就可以通过help()函数查看函数的说明
# 文档字符串非常简单,其实就是直接在函数的第一行写一个字符串就是文档字符串

def fn(a:int,b:int,c:str='hello'):
    '''
    这是一个文档字符串的示例

    函数的作用: ....
    函数的参数:
        a,作用,类型,默认值
        b,作用,类型,默认值
        c,作用,类型,默认值
    '''
    return 10

help(fn)

7、作用域global

'''
作用域(scope)
作用域指的是变量生效的区域

'''
b = 20
def fn():
    a = 10   # a定义在了函数内部,所以他的作用域就是函数内部,一旦出来函数就不能用了
    print('函数内部:','a =',a)
    print('函数内部:','b =',b)

fn()
#print('函数外部:','a =',a)
print('函数外部:','b =',b)

'''
在python中一共有两个作用域
全局作用域
    - 全局作用域在程序执行的时候创建,在程序执行结束时销毁
    - 所有函数以为的区域都是全局作用域
    - 在全局作用域中定义的变量,都属于全局变量,全局变量可以在任意测程序位置被访问
    
函数作用域
    - 函数作用域在函数调用时创建,在调用结束时被销毁
    - 函数每调用一次就会产生一个新的函数作用域
    - 在函数作用域中定义的变量,都是局部变量,它只能在函数内部被访问
变量的查找
    - 当我们使用变量时,会优先在当前作用域中寻找变量,如果有则使用
        如果没有则继续去上一级作用域寻找,如果有则使用
        如果依旧没有则继续去上一级作用域寻找,以此类推
        直到找到全局作用域,依然没有的话则抛出异常
            NameError: name 'b' is not defined
'''
def fn2():
    a = 30
    def fn3():
        a = 40    # 如果这里有的话,结果就是40
        print('fn3中:','a =',a)
    fn3()

fn2()


def fn3():
    #a = 10   # 如果有则为10 没有则为 40 ,,在函数中为变量赋值时,默认都是为全局变量赋值
    #   如果希望在函数内部修改为全局变量,则需要使用global关键字,来声明变量
    global a # 声明在函数内部的使用a 是全局变量,此时在去修改a时,就是在修改全局的a
    a = 10   # 修改全局变量
    print('a =',a)
fn3()
print('函数外部:','a =',a)

8、命名空间

'''
命名空间(namespace)
命名空间指的就是变量存储的位置,每一个变量都需要存储指定的命名空间中
每一个作用域都会有一个它对应的命名空间
全局命名空间,用来保存全局变量,函数的命名空间用来保存函数中的变量
命名空间实际上就是一个字典,是一个专门用来存储变量的字典

locals()用来获取当前作用域的命名空间
如果在全局作用域中调用local()则获取全局命名空间,如果在函数作用域中调用local()则获取函数命名空间
# 返回一个字典
'''
a = 40
scope = locals()   # 当前的命名空间
print(scope)
print(type(scope))
print(scope['a'])

# 向scope中添加一个key-value
scope['c'] = 1000 # 向字典中添加key-value就相当于在全局变量中添加了一个变量,不建议这么干
print(c)   # 有结果的哦

def fn4():
    a = 10
    # scope = locals()    # 在函数内部调用locals()会获取到函数的命名空间
    # scope['b'] = 200  # 可以通过这个scope来操作函数名称空间,但是也不建议这么做

    # glocal()  函数可以用来任意位置获取全局命名空间
    global_scope = globals()
    global_scope['a'] = 800
    print(scope)
fn4()
print(a)   # 这是函数中global_scope获取的全局命名空间的哦

9、递归介绍

'''
尝试求10的阶层(10!)
# 创建一个函数可以求任意说的阶层
# 1! = 1
# 2! = 1*2 = 2
# 3! = 1*2*3 = 6

'''

# 创建一个变量保存结果
n = 10
for i in range(1,10):
    n *= i
print(n)

# 创建一个函数,可以用来求任意数的阶乘
def factorial(n):
    '''
        该函数用来求任意数的阶乘
        参数:
            n 要求阶乘的数字
    '''
    # 创建一个变量,来保存结果
    result = n
    for i in range(1,n):
        result *= i
    return result

# 求10 的阶乘
print(factorial(10))

'''
递归式函数
递归简单理解就是自己应用自己
递归式函数,在函数中自己调用自己
'''

# 无穷递归,如果函数被调用,程序的内存会溢出,效果类似死循环
# def fn():
#     fn()

# 递归是解决问题的一种方式,它和循环很像
#   它的整体思想是,将一个大问题分解为一个个小问题,直到问题无法分解时,在解决问题
# 递归式函数的两个要件
#   1、基线条件
#       - 问题可以被分解为最小问题,当满足基线条件时,递归就不在执行了
#   2、递归条件
#       - 将问题继续分解的条件
# 递归和循环类似,基本是可以互相替代的
#       循环编写起来比较容易,阅读起来稍难
#       递归编写起来难,但是方便阅读
# 10! = 10 * 9
# 9! = 9 * 8
# 8! = 8 * 7
# ...
# 1! = 1

def factorial(n):
    '''
     该函数用来求任意数的阶乘

     参数:
        n 要求阶乘的数字

    '''
    # 基线条件,判断n是否为1,如果为1则此时不能在继续递归
    if n == 1:
        # 1 的阶乘就是1 ,直接返回1
        return 1
    # 递归条件
    return n * factorial(n - 1)
print(factorial(10))
练习
## 练习一:创建一个函数power来为任意数字做幂运算 n ** i
def power(n,i):
    '''
    power() 用来为任意的数字做幂运算
    参数
    :param n: 要做幂运算的数字
    :param i: 做幂运算的次数
    :return:
    '''
    if i == 1:
        # 求1次幂
        return n
    return n * power(n,i - 1)

print(power(2,4))

## 练习二:
#   创建一个函数,用来检查一个任意的字符串是否是回文字符串,,如果是返回True,不是返回False
#   回文字符串,字符串从前往后念和从后往前念是一样的
#       abcba
#     abcdefgfedcba
#   先检查第一个字符和最后一个是否一致,如果不一致则不是回文字符串
#   如果一致,则看剩余的部分是否是回文字符串
#   检查 abcdefgfedcba  是不是回文

def hui_wen(s):
    '''
    该函数用来检查指定字符串是否是回文字符串,如果是返回True,不是返回False
    aram s: 要检查的字符串
    :return:
    '''

    # 基线条件
    if len(s) < 2:
        # 字符串的长度小于2,则字符串一定是回文
        return True
    elif s[0] != s[-1]:     ## 或者用 return s[0] == s[-1] and hui_wen(s[1:-1])
        # 第一个字符和最后一个字符不相等,不是回文字符串
        return False
    return hui_wen(s[1:-1])

print(hui_wen('abcba'))

10、高阶函数,匿名函数,map

# 高级函数
# 接收函数作为参数,或者将函数作为返回值的函数就是高级函数
# 当我们使用一个函数作为参数时,实际上是将指定的代码传到指定的函数,也就是你传什么代码就是执行什么规则


#### 普通函数
# 创建一个列表
l = [1,2,3,4,5,6,7,8,9,10]
# 定义一个函数
#       可以将指定的列表中的所有偶数,保存到一个新的列表中返回
def fn(lst):
    new_list = []
    # 对列表进行判断
    for n in lst:
        if n % 2 == 0:
            new_list.append(n)
    return new_list

# print(fn(l))


#### 高级函数
# 定义一个函数,用来检查一个任意的数字是否是偶数
def fn2(i):
    if i % 2 == 0:
        return True
    return False
# 定义一个函数用来检查指定的数字是否大于5
def fn3(i):
    if i > 5 :
        return True
    return False

def fn(func,lst):
    new_list = []
    for n in lst:
        if func(n):
            new_list.append(n)

    #返回新列表
    return new_list

print(fn(fn3,l))
print(fn(fn2,l))

# 如果想求被3整除的数
# def fn4(i):
#     if i % 3 == 0:
#         return True
#     return False
# print(fn(fn4,l))





'''
官网上可以查看  https://docs.python.org/3/library/functions.html#filter

'''
# filter()
# filter() 可以从序列中过滤出符合条件的元素,保存到一个新的序列中
# 参数:
# 1、函数,根据该函数来过滤序列(可迭代的结构)
# 2、需要过滤的序列(可迭代的结构)
# 返回值
#   过滤后的新序列(可迭代的结构)

# fn4是作为参数传递进filter()函数中
#       而 fn4实际上就是一个作用,作为filter()的参数
#       filter()调用完毕后,fn4就已经没有用了

# 匿名函数 lambda 函数表达式
#   lambda函数表达式专门用来创建一些简单的函数,他是函数创建的又一种方式
#   语法: lambda  参数列表 : 返回值
# print(list(filter(fn4,l)))

def fn5(a,b):
    return a + b

lambda a,b:a + b

print(fn5(3,4))

print(type(lambda a,b:a + b))   # 证明它是函数
print((lambda a,b:a + b)(10,20))


fn6 = lambda a,b:a + b
print(fn6(4,9))

## 加入包上面的fn4函数用lamdba方式使用这样可以高度定制函数)(也叫语法糖函数)
r = filter(lambda i : i % 3 == 0, l)
print(list(r))

# map()
# map()函数可以对可迭代对象中的所有元素做指定的操作,然后将其添加到一个新的对象中返回
l = [1,2,3,4,5,6,7,8,9,10]
r = map(lambda i : i + 1,l)
print(list(r))

11、高级函数sort and sorted

# sort()
# 该方法用来对列表中的元素进行排序
# sort()方法默认是直接比较列表中的元素的大小
# 在sort()可以接收一个关键字参数,key
#   key需要一个函数作为参数,当设置了函数作为参数
#   每次都会以列表中的一个元素作为参数来调用函数,并且使用函数的返回值来比较元素的大小
l=['bb','aaaa','c','dddd','fff']
l.sort()
print(l)

l.sort(key=len)
print(l)

l = [2,5,'1',3,'6',4]
l.sort(key=int)
print(l)

# sorted()
#  这个函数和sort()的用法基本一致,但是sorted()可以对任意的序列进行排序
#   并且使用sorted()排序不会影响原来的对象,而是返回一个新对象

# l = [2,5,'1',3,'6',4]
l = "12345678899343224"

print('排序前:',l)
print(sorted(l,key=int))     # 对字符串进行排序
print('排序后:',l)

12、闭包

# 将函数作为返回值返回,也是一种高级函数
# 这个种高级函数我们称为闭包,通过闭包可以创建一些只有当前函数能访问的变量
#   可以将一些私有数据藏到闭包里

def fn():
    # 函数内部定义一个函数
    def inner():
        print('我是fn2')
    # 将内部函数inner作为返回值返回
    return inner

# r是一个函数,是调用fn()后返回的函数
# 这个函数实在fn()内部定义,并不是全局函数
# 所以这个函数总是能访问到fn()函数内部的变量
r = fn()
r()


#例题问:求对个数的平均值
nums = [50,30,20,10,88]
# sum()用来求一个列表中所有元素的和
print(sum(nums)/len(nums))

# 例题;创建一个函数,用来保存数值
# 形成闭包的要领
#       1、函数嵌套
#       2、将内部函数作为返回值返回
#       3、内部函数必须要使用到外部函数的变量
def make_averager():
    nums = []
    # 创建一个函数,用来计算平均值
    def averager(n):
        #将n添加到列表中
        nums.append(n)
        return sum(nums)/len(nums)

    return averager

averager = make_averager()

print(averager(10))     # 相当于 10 / 1
print(averager(10))     # 相当于 (10 +10)/2
print(averager(30))     # 相当于  (10 + 10 +30)/3
print(averager(30))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值