zoukankan      html  css  js  c++  java
  • python基础语法9 生成器,面向对象编程思想,三元表达式,列表生成式,生成器表达式(生成式),匿名函数,内置函数

    生成器

    1.什么是生成器?
      生成的工具。
      生成器是一个 "自定义" 的迭代器, 本质上是一个迭代器。

    2.如何实现生成器
      但凡在函数内部定义了的yield
      调用函数时,函数体代码不会执行
      会返回一个结果,该结果就是一个生成器

    yield:
      每一次yield都会往生成器对象中添加一个值。
      - yield只能在函数内部定义
      - yield可以保存函数的暂停状态


    yield与return:
      相同点:
        返回值的个数都是无限制的。

      不同点:
        return只能返回一次值,yield可以返回多个值,默认是元组,可以修改返回类型

    自定义的迭代器
    def func():
        print('开始准备下蛋')
        print('1---火鸡蛋1')
        yield '火鸡蛋1'
        print('2---火鸡蛋2')
        yield '火鸡蛋2'
        print('3---火鸡蛋3')
        yield '火鸡蛋3'
    
        print('取最后一个蛋,查看是否有')
    
    
    res是迭代器对象
    res = func()
    当我们通过__next__取值时,才会执行函数体代码。
    next(迭代器对象)
    print(next(res))
    print(next(res))
    print(next(res))
    
    迭代器对象.__next__()
    print(res.__next__())
    print(res.__next__())
    print(res.__next__())
    print(res.__next__())  # StopIteration报错

    自定义range功能,创建一个自定义生成器

    # 循环10次
    # for i in range(1, 11):
    # #     print(i)  # 1—10
    
    # python2: range(1, 5) ---> [1, 2, 3, 4]
    # python3: range(1, 5) ---> range对象 ---> 生成器 ---> 迭代器
    # res = range(1, 5)
    # print(res)
    
    # 自定义range功能,创建一个自定义的生成器
    # (1, 3)  # start--> 1  , end---> 5, move=2
    def my_range(start, end, move=1):  #
        while start < end:
            yield start
            start += move
    
    # g_range = my_range(1, 5)
    # print(g_range)
    #
    # for line in g_range:
    #     print(line)
    
    for line in my_range(1, 5, 2):
        print(line)

    面向过程编程

    思想!!!
    面向过程编程是一门编程思想。

    面向 过程 编程:
      核心是 '过程' 二字,过程 指的是一种解决问题的步骤,即先干什么再干什么
      基于该编程思想编写程序,就好比在设计一条工厂流水线,一种机械式的思维方式。

      优点:
        将复杂的问题流程化,进而简单化

      缺点:
        若修改当前程序设计的某一部分, 会导致其他部分同时需要修改, 扩展性差。

        牵一发而动全身,扩展性差。

    三元表达式

      可以将if...else...分支变成一行。

      语法:
        条件成立返回左边的值 if 判断条件 else 条件不成立返回右边的值

    def max2(num1, num2):
        res = num1 if num1 > num2 else num2
        return res
    
    res = max2(3, 2)
    print(res)
    
    
    # 需求: 让用户输入用户名,输入的用户如果不是tank,为其后缀添加_DSB
    username = input('请输入用户名:').strip()
    new_username = username if username == 'tank' else username + '_DSB'
    print(new_username)

    列表生成式

      可以一行实现生成列表。
      语法:
        list = [取出的每一个值、任意值 for 可迭代对象中取出的每一个值 in 可迭代对象]
        # for的右边是循环次数,并且可以取出可迭代对象中每一个值
        # for的左边可以为当前列表添加值
        list = [值 for 可迭代对象中取出的每一个值 in 可迭代对象]

        list = [值 for 可迭代对象中取出的每一个值 in 可迭代对象 if 判断]

    # 列表生成式
    list1 = [f'1{line}' for line in range(1, 101)]
    print(list1)
    
    
    #Demo: 将name_list列表中的每一个人后缀都添加_dsb
    name_list = ['jason', '饼哥(大脸)', 'sean', 'egon']
    new_name_list = [name + '_dsb' for name in name_list]
    print(new_name_list)
    
    
    #将name_list列表中的tank过滤掉,其他人后缀都添加_dsb
    name_list = ['jason', '饼哥(大脸)', 'sean', 'egon', 'tank']
    new_name_list = [name + '_dsb' for name in name_list if not name == 'tank']
    print(new_name_list)

    生成器表达式(生成式)

      - 列表生成式: 若数据量小时采用
        [line for line in range(1, 6)] ---> [1, 2, 3, 4, 5]
        优点:
          可以依赖于索引取值,取值方便

        缺点:
          浪费资源

      - 生成器生成式: 若数据量过大时采用
        () ---> 返回生成器
        (line for line in range(1, 6)) ---> g生成器(1, 2, 3, 4, 5)

        优点:
          节省资源

        缺点:
          取值不方便

    # 生成一个有1000个值的生成器
    g = (line for line in range(1, 1000001))
    # <generator object <genexpr> at 0x00000203262318E0>
    print(g)
    
    # 列表生成式实现
    list1 = [line for line in range(1, 1000001)]
    print(list1)
    #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10...]

    匿名函数:

      无名字的函数
      # :左边是参数, 右边是返回值
      lambda :

      PS: 原因,因为没有名字,函数的调用 函数名 + ()
      匿名函数需要一次性使用。
      注意: 匿名函数单独使用毫无意义,它必须配合 “内置函数” 一起使用的才有意义。

    有名函数:
      有名字的函数

    func = lambda x,y:x if x > y else y
    print(func(2,6))    #6
    
    calc = lambda x,y:x**y
    print(calc(2,5))    #32
    #按年龄排序
    l=[{'name':'alex','age':84},{'name':'oldboy','age':73},
       {'name':'egon','age':18}]
    l.sort(key=lambda x:x['age'])
    print(l)    
    # [{'name': 'egon', 'age': 18}, {'name': 'oldboy', 'age': 73}, {'name': 'alex', 'age': 84}]

    内置函数:

      range()
      print()
      len()

      # python内部提供的内置方法
      max, min, sorted, map, filter

      max: 获取可迭代对象中最大值

      min: 获取可迭代对象中最小值
      sorted: 对可迭代对象进行排序

        默认是: 升序
        reverse=True: 降序

      map: 映射

      reduce: 合并  

      filter: 过滤

    # max求最大值   max(可迭代对象)
    list1 = [1, 2, 3, 4, 5]
    
    # max内部会将list1中的通过for取出每一个值,并且进行判断
    print(max(list1))  #
    
    dict1 = {
        'tank': 1000,
        'egon': 500,
        'sean': 200,
        'jason': 500
    }
    
    # 获取dict1中薪资最大的人的名字
    # 字符串的比较: ASCII
    print(max(dict1, key=lambda x: dict1[x]))   #tank  因为以索引判断,所以key就是索引,参数x为索引

    # 获取dict1中薪资最小的人的名字
    print(min(dict1, key=lambda x:dict1[x]))

     
    # sorted: 默认升序(从小到大) reverse:反转 reverse默认是False
    list1 = [10, 2, 3, 4, 5]
    print(sorted(list1))
    # reverse=True--> 降序
    print(sorted(list1, reverse=True))
    
    dict1 = {
        'tank': 100,
        'egon': 500,
        'sean': 200,
        'jason': 50
    }
    # new_list = ['egon', 'sean', 'tank', 'jason']
    new_list = sorted(dict1, key=lambda x: dict1[x], reverse=True)
    print(new_list)

     map()

      map(函数地址, 可迭代对象) ---> map对象
      map会将可迭代对象中的每一个值进行修改,然后映射一个map对象中,
      可以再将map对象转换成列表/元组。
      注意: 只能转一次。

    name_list = ['egon', 'jason', 'sean', '大饼', 'tank']
    map_obj = map(lambda name: name + '喜欢吃生蚝' if name == 'tank' else name + 'DJB', name_list)
    print(map_obj)  # map_obj ---> list/tuple
    print(list(map_obj))  # map_obj ---> 生成器(迭代器) ---> 用完后,不能再取了
    print(tuple(map_obj))  # map对象只能调用一次,第二次返回空
    
    # 结果
    # <map object at 0x00000000021CF4A8>
    # ['egonDJB', 'jasonDJB', 'seanDJB', '大饼DJB', 'tank喜欢吃生蚝']
    # ()
    list1=[1,2,3,4,5]
    res=map(lambda x:x**2,list1)
    print(list(res))    # [1, 4, 9, 16, 25]
    
    def square(x):
        return x**2
    ----------------------------------------
    list1=[1,2,3,4,5]
    res=map(square,list1)
    print(list(res))    # [1, 4, 9, 16, 25]

    reduce()    # 函数必须接受两个参数

      reduce(函数地址, 可迭代对象, 默认为0)
      reduce(函数地址, 可迭代对象, 初始值)

    # reduce
    from functools import reduce    #需要导入模块
    # 每次从可迭代对象中获取两个值进行合并,
    # 初始值: 执行reduce函数时,都是从初始值开始合并
    reduce(lambda x, y: x + y, range(1, 101), 0)# 先算x=0 + y=1,和为x再+2,和再+3...+100
    
    # 需求: 求1——100的和
    # 普通
    init = 1000
    for line in range(1, 101):
        init += line
    
    print(init)  # 5050
    
    # reduce
    res = reduce(lambda x, y: x + y, range(1, 101), 1000)# 先算x=1000 + y=1,和为x再+2,和再+3...+100
    print(res)  # 6050

    filter()

      filter(函数地址, 可迭代对象) --> filter 对象

    # filter
    name_list = ['egon_dsb', 'jason_dsb',
                 'sean_dsb', '大饼_dsb', 'tank']
    # filter_obj = filter(lambda x: x, name_list)
    
    # 将后缀为_dsb的名字 “过滤出来”
    # filter会将函数中返回的结果为True 对应 的参数值 “过滤出来”
    # 过滤出来的值会添加到 filter对象中
    filter_obj = filter(lambda name: name.endswith('_dsb'), name_list)  #是否结尾为'_dsb',如果为true,返回那个值
    print(filter_obj)   #<filter object at 0x0000000001E4C5C0>
    print(list(filter_obj))  # ['egon_dsb', 'jason_dsb', 'sean_dsb', '大饼_dsb']
    # print(tuple(filter_obj))
    ----------------------------------------------------------------
    
    name_list = ['egon_dsb', 'jason_dsb',
                 'sean_dsb', '大饼_dsb', 'tank']
    filter_obj = filter(lambda x:x[-3:] != 'dsb',name_list)     print(filter_obj)
    print(list(filter_obj))     # ['tank']
  • 相关阅读:
    listview删除item
    标准listview加图标布局
    android事件消费机制,从外传到里面,里面具有优先选择权,如果里面的不需要,则传递给外面一层消费
    listview 按最新数据展示
    给listview添加数据,添加数据之后即刻显示出来,并把数据放在listview列表的最前面
    EditText限制输入长度和限定输入数字
    josn解析常见的几种方法
    bnu Robots on a grid
    hdu 1348 Wall
    hdu poj Oulipo
  • 原文地址:https://www.cnblogs.com/ludingchao/p/11859317.html
Copyright © 2011-2022 走看看