09,匿名函数、内置函数和闭包

1,匿名函数

匿名函数:一句话函数
构建匿名函数
func1 = lambda a, b: a + b      # lambda 相当于def定义函数,func1相当于函数名  a,b是形参  a +b 是返回值
print(func1(1, 2))              # 1,2 是实参

# 写匿名函数:接收一个可切片的数据,返回索引为0与2的对应的元素(元组形式)。
func2 = lambda x: (x[0], x[2])
print(func2('hjfg'))
#
# 写匿名函数:接收两个int参数,将较大的数据返回。

func3 = lambda x, y: max(x, y)
print(func3(55, 12))

func3 = lambda x, y: x if x > y else y
print(func3(11,57))

2,内置函数

# 1,abs(): 返回绝对值
i = -5
print(abs(i))  # 5
print(1, 2, 3, 4, 5, sep='|')
# print(self, *args, sep=' ', end='\n', file=None):
# sep='':改变元素中的间隔符        end='\n':自动换行


# 2,enumerate():
# 用于将可迭代对象(如列表、元组等)中的数据转换为枚举对象。枚举对象中的每个元素都自动绑定了一个索引值,从 0 开始计数
fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits):
    print(index, fruit)

# 输出:
# 0 apple
# 1 banana
# 2 cherry



# 3,filter():筛选过滤---相当于列表推导式的筛选模式
'''
语法: filter(function, iterable)
function: 用来筛选的函数, 在filter中会自动的把iterable中的元素传递给function,
            然后根据function返回的True或者False来判断是否保留此项数据
iterable: 可迭代对象
'''
lst = [{'id': 1, 'name': 'alex', 'age': 18},
       {'id': 1, 'name': 'wusir', 'age': 17},
       {'id': 1, 'name': 'taibai', 'age': 16}, ]

print([i for i in lst if i['age'] > 16])   # [{'id': 1, 'name': 'alex', 'age': 18}, {'id': 1, 'name': 'wusir', 'age': 17}]
ls = filter(lambda e: e['age'] > 16, lst)
print(ls)       # <filter object at 0x000001425F515E48> 返回的是一个迭代器
print(list(ls))     # [{'id': 1, 'name': 'alex', 'age': 18}, {'id': 1, 'name': 'wusir', 'age': 17}]


# 4,map():映射函数---相当于列表推导式的循环模式
'''
语法: map(function,iterable) 可以对可迭代对象中的每一个元素进映射,分别取执行function
计算列表中每个元素的平方,返回新列表
'''
lst = [1, 2, 3, 4, 5]
def func(s):
    return s * s

mp = map(func, lst)
print(mp)
print(list(mp))
# 改写成lambda
lst = [1, 2, 3, 4, 5]
print(list(map(lambda s: s * s, lst)))
# 计算两个列表中相同位置的数据的和
lst1 = [1, 2, 3, 4, 5]
lst2 = [2, 4, 6, 8, 10]
print(list(map(lambda x, y: x + y, lst1, lst2)))


# 5,min()  **********:求最小值
print(min([1, 2, 3]))  # 返回此序列最小值
ret = min([1, 2, -5, ], key=abs)  # 按照绝对值的大小,返回此序列最小值
print(ret)
# 加key是可以加函数名,min自动会获取传入函数中的参数的每个元素,然后通过你设定的返回值比较大小,返回最小的传入的那个参数
# 凡事可以加key的,他会自动的将可迭代对象中的每个元素按照传入key对应的函数中,
# 以返回值比较大小。
# 求出值最小的键
dic = {'a': 3, 'b': 2, 'c': 1}


def func(args):
    return dic[args]


print(min(dic, key=lambda args: dic[args]))
#
# 求出值最小的键值对
l2 = [('太白', 18), ('alex', 73), ('wusir', 35), ('口天吴', 41)]
# print(min(l2))
print(min(l2, key=lambda x: x[1]))  # ('太白', 18)
print(min(l2, key=lambda x: x[1])[0])       # 太白
print(min(l2, key=lambda x: x[1])[1])       # 18
# 6,max()  **********:最大值与最小值用法相同


# 7,open():
# 用于打开文件并返回一个文件对象。通过这个文件对象可以进行读写操作
open("文件名", mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)


# 8,range():
# 配合for循环使用,相当于一个前闭后开的区间

# 9,print():屏幕输出。
print(111, 222, 333, sep='*')  # 111*222*333
print(111, end='')
print(222)  # 两行的结果 111222


# 10,len():
# 用于获取对象(如字符串、列表、元组、字典等可迭代对象)的长度或元素数量
s = "Hello, world!"
length = len(s)
print(length)  # 输出: 13


# 11,list():将一个可迭代对象转换成列表
l1 = [1,2,3,4]
l2 = list()
l3 = list('sdrjsdrhsdg')
print(l2)       # []
print(l3)       # ['s', 'd', 'r', 'j', 's', 'd', 'r', 'h', 's', 'd', 'g']


# 12,dict():通过相应的方式创建字典
# 直接创建
# 1,
dic = dict([(1, 'one'), (2, 'two'), (3, 'three')])
# 2,
dic1 = dict(one=1,two=2,three=3)
print(dic)      # {1: 'one', 2: 'two', 3: 'three'}
print(dic1)     # {'one': 1, 'two': 2, 'three': 3}
# 3,fromkeys
dic2 = dict.fromkeys('abc',100)
print(dic2)      # {'a': 100, 'b': 100, 'c': 100}
dic3 = dict.fromkeys([1, 2, 3], [])
dic3[1].append(666)  # {1: [666], 2: [666], 3: [666]}  共用一个,提个变全都变
print(dic3)


# 13,str():将一个可迭代对象转换成字符串
list1 = [1, 2, 3, 4, 5, 6, 7, 8]
print(str(list1), type(str(list1)))     # 输出的内容看起来像列表,其实是字符串


# 14,reversed():将一个序列翻转, 返回翻转序列的迭代器
l = reversed('你好')  # l 获取到的是一个生成器
print(list(l))
ret = reversed([1, 4, 3, 7, 9])
print(list(ret))  # [9, 7, 3, 4, 1]
l1 = [1,5,8,6,4,3]
l1.sort(reverse=True)
print(l1)       # [8, 6, 5, 4, 3, 1]


# 15,set():将一个可迭代对象转换成字集合,创建集合
lt = [1, 2, 3, 4, 5, 6]
print(set(lt))

# 16,sorted():排序函数
'''
语法: sorted(iterable, key=None, reverse=False)

iterable: 可迭代对象

key: 排序规则(排序函数), 在sorted内部会将可迭代对象中的每一个元素传递给这个函数的参数.根据函数运算的结果进行排序

reverse: 是否是倒叙, True
倒叙
False
正序
'''


lst = [1, 3, 2, 5, 4]
lst2 = sorted(lst)
print(lst)  # 原列表不会改变
print(lst2)  # 返回的新列表是经过排序的

lst3 = sorted(lst, reverse=True)
print(lst3)
l2 = [('太白', 18), ('alex', 73), ('wusir', 35), ('口天吴', 41)]
print(sorted(l2, key=lambda x: x[1])) # 从低到高   # [('太白', 18), ('wusir', 35), ('口天吴', 41), ('alex', 73)]
print(sorted(l2, key=lambda x: x[1],reverse=True))  # 从高到低  # [('alex', 73), ('口天吴', 41), ('wusir', 35), ('太白', 18)]


# 17,sum():求和
print(sum([1, 2, 3]))
print(sum((1, 2, 3), 100))


# 18,tuple():将一个可迭代对象转换成元组
lst = [1, 2, 3, 4, 5, 6]
print(tuple(lst))

# 19,type():
# 输出一个变量的数据类型
def func():
    return "你好"
print(type(func))

lst = [1, 2, 3, 4]
print(type(lst))

str = 'rthfb8675'
print(type(str))

# 20,zip() ***:拉链方法。函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,
lst1 = [1, 2, 3]
lst2 = ['a', 'b', 'c', 'd']
lst3 = (11, 12, 13, 14, 15)
for i in zip(lst1, lst2, lst3):
    print(i)

obj = zip(lst1, lst2, lst3)
print(obj)  # <zip object at 0x000002B1440C1808>

for i in obj:
    print(i)

print(list(obj))  # [(1, 'a', 11), (2, 'b', 12), (3, 'c', 13)]

# 21,dir():
# 获取一个对象的所有方法
print(dir(print))

# 22,reduce
from functools import reduce


def func(x, y):
    '''
    第一次:x y : x = 11  y = 2      x + y =   记录: 13
    第二次:x y : x = 13  y = 3      x + y =   记录: 16
    第三次:x y : x = 16  y = 4      x + y =   记录: 20
    '''
    return x + y


l = reduce(func, [11, 2, 3, 4])
print(l)  # 20

3,递归函数

递归函数:就是自己调用自己
可以用来跑分,测试电脑性能
import sys
sys.setrecursionlimit(10000000)     # 设置递归最大深度
count = 0
def func():
    global count
    count += 1
    print(count)
    func()
    print(465)

func()

RecursionError 递归错误
python中递归最大深度1000层:限制1000是为了节省内存,不让用户无限的使用空间
    1,递归要尽量控制次数,如果需要很多层才能解决问题,那就不适合用递归解决
    2,循环和递归的关系
        递归不是万能的
        递归比循环更占用内存
# 递归函数一定要停下来
# 一个递归函数想要结束,必须在函数内写一个return,并且return的条件必须是一个可达到的条件
count = 0
def func():
    global count
    count += 1
    print(count)
    if count == 3:return
    func()
    print(465)

func()

递归题目的练习

# 1,计算阶乘
# 递归
# 循环
def func(n):
    if n == 1:return n
    else:
        return n * func(n-1)

x = int(input('请输入要计算的数字阶乘:'))
ret = func(x)
print(ret)

# 2,用os模块查看一个文件夹下的所有文件,这个文件夹下面还有文件夹
import os


def show_file(path):
    name_list = os.listdir(path)  # os.listdir是将所有的文件夹放到一个列表中去
    for name in name_list:
        abs_path = os.path.join(path, name)
        if os.path.isfile(abs_path):
            print(name)
        elif os.path.isdir(abs_path):
            show_file(abs_path)


show_file('D:\python代码文件\python全栈学习')

# 3,用os模块计算文件夹下所有的文件大小,这个文件夹下面还有文件夹
import os
def dir_size(path):
    size = 0
    name_list = os.listdir(path)
    for name in name_list:
        abs_path = os.path.join(path, name)
        if os.path.isfile(abs_path):
            size += os.path.getsize(abs_path)
        else:
            ret = dir_size(abs_path)
            size += ret
    return size


path = 'D:\python代码文件'
ret = dir_size(path)
print(ret)      # 2080215单位是bt


# 4,计算斐波那契数列
# 找第100项的值
# 1 1 2 3 5 8
# 方法一:递归
def func(n):
    if n == 1 or n == 2:
        return 1
    else:
        return func(n-1) + func(n-2)

ret = func(100)
print(ret)

# 方法二:循环
def func(n):
    a = 1
    b = 1
    while n > 2:
        a, b = b, a+b
        n -= 1
    return b

ret = func(100)
print(ret)

# 方法三:递归2
def func(n, a=1, b=1):
    if n == 1 or n == 2:
        return b
    else:
        a, b = b, a+b
        return func(n - 1, a, b)


ret = func(100)
print(ret)

# 方法四:生成器 返回的是斐波那契数列
def func(n):
    a = 1
    if n == 1:
        yield 1
        return
    yield a
    b= 1
    yield b
    while n > 2:
        a,b = b,a+b
        yield b
        n -= 1

for i in func(100):
    print(i)


# 5,三级菜单    可能是n级
# 例:河南省-郑州市-金水区
menu = {
    '北京': {
        '海淀': {
            '五道口': {
                'soho': {},
                '网易': {},
                'google': {}
            },
            '中关村': {
                '爱奇艺': {},
                '汽车之家': {},
                'youku': {},
            },
            '上地': {
                '百度': {},
            },
        },
        '昌平': {
            '沙河': {
                '老男孩': {},
                '北航': {},
            },
            '天通苑': {},
            '回龙观': {},
        },
        '朝阳': {},
        '东城': {},
    },
    '上海': {
        '闵行': {
            "人民广场": {
                '炸鸡店': {}
            }
        },
        '闸北': {
            '火车战': {
                '携程': {}
            }
        },
        '浦东': {},
    },
    '山东': {},
}
#
# # 方法一:
def menu_func(menu):
    flag = True
    while flag:
        for name in menu:
            print(name)
        key = input('>>>').strip()
        if menu.get(key):
            dic = menu[key]
            flag = menu_func(dic)
        elif key.upper() == 'B':
            return True
        if key.upper() == 'Q':
            return False


menu_func(menu)
print('123')


# 方法二:
def menu_func(menu):
    while True:
        for name in menu:
            print(name)
        key = input('>>>').strip()
        if menu.get(key):
            dic = menu[key]
            flag = menu_func(dic)
            if not flag:
                return False
        elif key.upper() == 'B':
            return True
        if key.upper() == 'Q':
            return False


menu_func(menu)
print('123')

4,闭包

闭包定义:
    1,闭包是嵌套在函数中的函数,只存在嵌套函数中
    2,内层函数对外层函数非全局变量的引用(使用),就会形成闭包
被引用的的非全局变量也称作自由变量,这个自由变量会与内层函数产生一个绑定关系,
自由变量不会在内存中消失
闭包的作用:保证数据安全
封闭的东西:保证数据的安全。

必须是函数中嵌套函数

案例:

'''
整个历史中的某个商品的平均收盘价。什么叫平局收盘价呢?就是从这个商品一出现开始,
每天记录当天价格,然后计算他的平均值:平均值要考虑直至目前为止所有的价格。

比如大众推出了一款新车:小白轿车。

    第一天价格为:100000元,平均收盘价:100000元

    第二天价格为:110000元,平均收盘价:(100000 + 110000)/2 元

    第三天价格为:120000元,平均收盘价:(100000 + 110000 + 120000)/3 元

'''
方案一 :全局变量  数据不安全
# 方案一
l1 = []     # 全局变量  数据不安全


def make_averager(new_value):
    l1.append(new_value)
    total = sum(l1)
    averager = total / len(l1)
    return averager


print(make_averager(100000))
print(make_averager(110000))
print(make_averager(120000))
print(make_averager(90000))
# 很多很多的代码....
print(make_averager(120000))
print(make_averager(90000))
方案二: 数据安全,l1不能放全局变量中
每次执行时,l1列表都会重新赋值成为空列表[],不能进行累加
l1 = []  # 全局变量  数据不安全


def make_averager(new_value):
    l1 = []
    l1.append(new_value)
    total = sum(l1)
    averager = total / len(l1)
    return averager


print(make_averager(100000))
print(make_averager(110000))
print(make_averager(120000))
print(make_averager(90000))
# 很多很多的代码....
print(make_averager(120000))
print(make_averager(90000))
方案三:闭包
def make_averager():
    l1 = []

    def averager(new_value):
        l1.append(new_value)
        total = sum(l1)
        return total / len(l1)

    return averager


avg = make_averager()  # averager
print(avg(100000))
print(avg(110000))
print(avg(120000))
print(avg(90000))
如何判断一个嵌套函数是不是闭包                                                           1,闭包是嵌套在函数中的函数,只存在嵌套函数中
             2,内层函数对外层函数非全局变量的引用(使用),就会形成闭包

 例如:

# # 例一
def wrapper():
    a = 1

    def inner():
        print(a)

    return inner()


wrapper()

# # 例二:
a = 2
def wrapper():
    def inner():
        print(a)
    return inner()

wrapper()



例一是闭包:是嵌套函数,内层函数也调用了非全局变量。
例二不是闭包:是嵌套函数,但是内层函数没有调用外层函数中的非全局变量。

5,练习题目

 # 1,
# 看代码写结果(新浪微博面试题)
def func():
    for num in range(10):
        pass
    v4 = [lambda: num + 10, lambda: num + 100, lambda: num + 100, ]
    result1 = v4[0]()
    result2 = v4[1]()
    result3 = v4[2]()
    print(result1, result2, result3)


func()

# 2,
# 用map()函数处理字符串列表,把列表中所有人的名字后面都加上'_sb'。例:'alex_yy'
name = ['oldboy', 'alex', 'wusir']
# 方法一
name = ['oldboy', 'alex', 'wusir']
print([i + '_yy' for i in name])
# 方法二
print(list(map(lambda x:x+'_sb',name)))


# 3,用map来处理下述l,然后用list得到一个新的列表。列表中每个人的名字都是ab结尾
l = [{'name': 'alex'}, {'name': 'y'}]
l = [{'name': 'alex'}, {'name': 'y'}]
print(list(map(lambda x: x['name'] + 'ab', l)))

# 4,有下列三种数据类型,
l1 = [1, 2, 3, 4]
l2 = ['oldboy', 'alex', 'wusir', '太白', '日天']
tu = ('**', '***', '****', '******')
# 写代码,最终得到的是(每个元组第一个元素大于2,第三个*至少是4个。),例:[(3,'wusir','****'),(4,'太白','******')]这样的数据。
l1 = [1, 2, 3, 4]
l2 = ['oldboy', 'alex', 'wusir', '太白', '日天']
tu = ('**', '***', '****', '******')
# 方法一
print(list(i for i in zip(l1, l2, tu) if i[0] > 2 and len(i[2]) >= 4))
# 方法二
print(list(filter(lambda x: x[0] > 2 and len(x[-1]) >= 4, zip(l1, l2, tu))))


# 5,有如下数据类型(实战题)
"""
l1 = [{'sales_volum': 0},
      {'sales_volum': 108},
      {'sales_volum': 337},
      {'sales_volum': 475},
      {'sales_volum': 369},
      {'sales_volum': 172},
      {'sales_volum': 9},
      {'sales_volum': 58},
      {'sales_volum': 272},
      {'sales_volum': 456},
      {'sales_volum': 440},
      {'sales_volum': 239}, ]
将l1按照列表中的每个字典的values大小进行排序,形成一个新的列表。
l1 = [{'sales_volum': 0},
      {'sales_volum': 108},
      {'sales_volum': 337},
      {'sales_volum': 475},
      {'sales_volum': 369},
      {'sales_volum': 172},
      {'sales_volum': 9},
      {'sales_volum': 58},
      {'sales_volum': 272},
      {'sales_volum': 456},
      {'sales_volum': 440},
      {'sales_volum': 239}, ]
"""


print(list(sorted(l1, key=lambda x: x['sales_volum'])))     # 从小到大
print(list(sorted(l1, key=lambda x: x['sales_volum'], reverse=True)))       # 从大到小


# 5,求结果(面试题)
v = [lambda:x for x in range(10)]       # 列表
print(v)       
print(v[1])     
print(v[0]())   


# 是内存地址的一个列表
# <function <listcomp>.<lambda> at 0x000002AAB0B3FE58>
# 执行第一个内存地址 9


# 6,求结果(面试题)***
v = (lambda:x for x in range(10))        # 元组
print(v)        
print(v[0])    
print(v[0]())     
print(next(v))      
print(next(v)())    



# <generator object <genexpr> at 0x0000024E9EE8C348>
# 报错
# 报错
# <function <genexpr>.<lambda> at 0x000001FA813AFDC8>
# 上一步不执行单独执行结果是0,上一步执行完再执行结果是1





# map(str,[1,2,3,4,5,6,7,8,9])输出的是什么?
print(list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])))



# 7,求结果(面试题)
def num():
    return [lambda x: i * x for i in range(4)]


print([m(2) for m in num()])

# 相当于;
def num():
      lst = []
      for i in range(4):
            lst.append(lambda x: i*x)     # 相当于lambda是一个内层函数,for循环结束后才运行lambda所以i的值应该是最后一个3
      print(i)
      return lst
num()




# 8,写一个函数完成三次登录功能:

'''
    1,用户的用户名密码从一个文件register中取出。
    2,register文件中包含多个用户名,密码:用户名密码通过|隔开,每个人的用户名密码占用。
    3,完成三次验证,三次验证不成功则登录失败,登录失败则返回False。
    4,登录成功返回True。
    5,passwd文件内容:
        大壮|123
        太白|666
        b哥|999
        alex|123
'''


def login():
    dic = {}
    with open('passwd', encoding='utf-8') as file:
        for line in file:
            data = line.split("\n")
            a, b = data[0].split("|")
            dic[a] = b
    count = 0
    flag = True
    while flag:
        useranme = str(input('用户名:'))
        password = str(input('密 码:'))
        if useranme in dic.keys() and password == dic[useranme]:
            print('登录成功!')
            break
        else:
            print(f'用户名或密码不正确,剩下{2-count}次机会')
            count += 1
            if count == 3:
                flag = False


login()

# 9,再写一个函数完成注册功能:
'''
    1,用户输入用户名密码注册。
    2,注册时要验证(文件register中) 用户名是否存在,如果存在则让其重新输入用户名,如果不存在,则注册成功。
    3,注册成功后,将注册成功的用户名,密码写入register文件,并以|隔开。
    4,注册成功后,返回Ture,否则返回False。
'''

更多内容可以查看自己学python的过程,简单笔记。-CSDN博客

更多内容可以查看自己学python的过程,简单笔记。-CSDN博客

更多内容可以查看自己学python的过程,简单笔记。-CSDN博客

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值