Python-Level1-day17:yield浅出生成器终极版;内置生成器与枚举函数 enumerate;zip合拆应用;生成器深度体验价值,生成器推导式

作业
1. 三合一
2. 当天练习独立完成
3. 迭代器遍历图形控制器
class GraphicController:
        pass
​
controller = CommodityController()
controller.add_graphic("圆形")
controller.add_graphic("矩形")
controller.add_graphic ("三角形")
​
for item in controller:
    print(item)
​
4. 将迭代器版本的商品控制器改为生成器yield实现
​
​
5. 对员工管理系统进行异常处理
    employee_system
​
6. 完成mvc版本2048
    -- 将核心算法移动到GameController类中
       提示:全局变量改为实例变量
            函数改为实例方法
    -- 创建GameView类,根据wsad键移动数字.
​
#遍历图形控制器:一个自己的类怎么参与循环的过程
class GraphicIteror:
    def __init__(self, data):
        self.__data = data
        self.__index = -1
​
    def __next__(self):
        if self.__index == len(self.__data) - 1:
            raise StopIteration()
        self.__index += 1
        return self.__data[self.__index]
​
class GraphicController:
    def __init__(self):
        self.__graphics = []
​
    def add_graphic(self, gra):
        self.__graphics.append(gra)
​
    def __iter__(self):
        return GraphicIteror(self.__graphics)
​
controller = GraphicController()
controller.add_graphic("圆形")
controller.add_graphic("矩形")
controller.add_graphic("三角形")
​
for item in controller:
    print(item)
​
# for原理
iterator = controller.__iter__()
while True:
    try:
        item = iterator.__next__()
        print(item)
    except StopIteration:
        break
​
"""
1.父类iter()物理上代码不存在,即python找不到他,但思想上存在,
子类小鸭子原则,调用父类,执行子类。
面向对象父类约束与隔离的强大
​
2.next为什么不直接写入到与iter相同类中?
因为每个创建的对象都需要具有这个方法才能实现迭代,
将其单独抽离到另外一个类中,通过跨类减少代码的重复性
"""
# 将迭代器版本的商品控制器改为迭代器yield实现
​
class CommodityController:
    def __init__(self):
        self.__comditys = []
​
    def add_commodity(self, cmd):
        self.__comditys.append(cmd)
​
    def __iter__(self):#1995年就确定下的函数
        # 生成代码的大致规则:了解
        # 1. 将yield关键字前面的代码作为__next__函数体
        # 2. 将yield关键字前面的数据作为__next__返回值
        index = 0
        yield self.__comditys[index]
​
        index += 1
        yield self.__comditys[index]
​
        index += 1
        yield self.__comditys[index]
​
​
controller = CommodityController()
controller.add_commodity("屠龙刀")
controller.add_commodity("倚天剑")
controller.add_commodity("芭比娃娃")
​
for item in controller:
    print(item)
​
# for原理
iterator = controller.__iter__()#调试直接不进入这个函数
while True:
    try:
        item = iterator.__next__()#调试进入yield
        print(item)
    except StopIteration:
        break
​

 

from bll import EmployContler
from usl import EmployView
import sys
​
print(sys.path)
if __name__ == '__main__':
    try:
        ctrontrl = EmployContler()
        view1 = EmployView(ctrontrl)
        view1.main()
    except:
        print("这叫全局异常处理,不能针对有效细节,不是我们想要的异常处理")
"""
就算没有手动标蓝,也不报错,原因是默认这个文件夹下面导入路径
"""
​
class EmployModel:
    def __init__(self, name="", money=0, eid=0, id=""):
        self.name = name
        self.money = money
        self.eid = eid
        self.id = id
​
    def __str__(self):
        return f"姓名{self.name},工资{self.money},编号{self.eid}"
​
    def __eq__(self, other):
        return self.id == other
​
from model import EmployModel
​
​
class EmployView:
    def __init__(self, ctrl):
        self.__ctrl = ctrl  # type:EmployContler
​
    def __display(self):
        print("按1键录入员工信息")
        print("按2键显示员工信息")
        print("按3键修改员工信息")
        print("按4键删除员工信息")
​
    def __select_maue(self):
        item = input("请输入选项")
        if item == "1":
            self.__input()
        elif item == "2":
            self.__show()
        elif item == "3":
            self.__modity_emp()
        elif item == "4":
            self.__delete_employ()
​
    def __get_right(self, message):  # 妙啊
        while True:
            try:
                num = int(input(message))
                return num
            except:
                print("输入有误")
​
    def __input(self):
        emp = EmployModel()
        emp.name = input("请输入员工姓名")
        emp.money = self.__get_right("请输入员工薪资")
        emp.eid = self.__get_right("请输入员工编号")
        self.__ctrl.storage(emp)
​
    def __show(self):
        for item in self.__ctrl.list_employ:
            print(item)
​
    def __modity_emp(self):
        emp = EmployModel()
        emp.id = self.__get_right("请输入要修改的id")
        emp.name = input("请输入要修改的姓名")
        emp.eid = self.__get_right("请输入要修改的编号")
        emp.money = self.__get_right("请输入要修改的薪资")
        if self.__ctrl.modity_employ(emp):
            print("修改成功")
        else:
            print("修改失败")
​
    def __delete_employ(self):
        id = self.__get_right("请输入要修改的id")
        if self.__ctrl.delete1_emp(id):
            print("删除成功")
        else:
            print("删除失败")
​
    def main(self):
        while True:
            self.__display()
            self.__select_maue()
from model import EmployModel
​
​
class EmployContler:
    __startid = 0
​
    @classmethod
    def __set_id(cls, emp: EmployModel):
        cls.__startid += 1
        emp.id = cls.__startid
​
    def __init__(self):
        self.__list_employ = []
​
    @property
    def list_employ(self):
        return self.__list_employ
​
    def storage(self, emp: EmployModel):
        EmployContler.__set_id(emp)
        self.__list_employ.append(emp)
​
    def modity_employ(self, emp) -> bool:
        for item in self.__list_employ:
            if item.id == emp.id:  # 寻址可以修改item 从而修改list_employ 妙啊
                item.name = emp.name
                item.eid = emp.eid
                item.money = emp.money
            return True
        return False
​
    def delete1_emp(self, id) -> bool:
        if id in self.__list_employ:
            self.__list_employ.remove(id)
            return True
        return False
​
from bll import GameController
from usl import GameView
​
# import bll  为什么这里将整个模块导入不行
# import usl
​
ctr1 = GameController()
view1 = GameView(ctr1)
view1.main()
​
from bll import GameController
​
​
class GameView:
    def __init__(self, controller):
        self.__controller = controller
​
    def __key_conter(self):
        key = input("wasd")
        if key == "w":
            self.__controller.move_up()
        elif key == "s":
            self.__controller.move_down()
        elif key == "a":
            self.__controller.move_left()
        elif key == "d":
            self.__controller.move_right()
​
    def __map_square(self):
        for line in self.__controller.map:
            for item in line:
                print(item, end="\t")  # 元素之间弹性空格
            print()  # 换行
​
    def main(self):
        while True:
            self.__map_square()
            self.__key_conter()
​
class GameController:
​
    def __init__(self):
        self.__map = [
            [2, 0, 0, 2],
            [4, 2, 0, 2],
            [2, 4, 2, 4],
            [0, 4, 0, 4],
        ]
        self.__list_merge = None
​
    @property
    def map(self):
        return self.__map
​
    def __zero_to_end(self):
        for i in range(len(self.__list_merge) - 1, -1, -1):
            if self.__list_merge[i] == 0:
                del self.__list_merge[i]
                self.__list_merge.append(0)
​
    def __merge(self):
        self.__zero_to_end()
        for i in range(len(self.__list_merge) - 1):
            if self.__list_merge[i] == self.__list_merge[i + 1]:
                self.__list_merge[i] += self.__list_merge[i + 1]
                del self.__list_merge[i + 1]
                self.__list_merge.append(0)
​
    def move_left(self):
        for line in self.__map:
            self.__list_merge = line
            self.__merge()
​
    def move_right(self):
        for line in self.map:
            self.__list_merge = line[::-1]
            self.__merge()
            line[::-1] = self.__list_merge
​
    def __square_matrix_transposition(self):
        for c in range(1, len(self.__map)):  # 1 2 3
            for r in range(c, len(self.__map)):
                self.__map[r][c - 1], self.__map[c - 1][r] = self.__map[c - 1][r], self.__map[r][c - 1]
​
    def move_up(self):
        self.__square_matrix_transposition()
        self.move_left()
        self.__square_matrix_transposition()
​
    def move_down(self):
        self.__square_matrix_transposition()
        self.move_right()
        self.__square_matrix_transposition()
​
​
if __name__ == '__main__': # 测试
    controller = GameController()
    controller.move_down()
    controller.move_up()
    controller.move_left()
    controller.move_right()
    print(controller.map)
​


生成器 generator

  1. 定义:能够动态(循环一次计算一次返回一次)提供数据的可迭代对象。

  2. 作用:在循环过程中,按照某种算法推算数据,不必创建容器存储完整的结果,从 而节省内存空间。数据量越大,优势越明显。

  1. 以上作用也称之为延迟操作或惰性操作,通俗的讲就是在需要的时候才计算结果, 而不是一次构建出所有结果。

生成器函数

  1. 定义:含有 yield 语句的函数,返回值为生成器对象。

  2. 语法

-- 创建:

def 函数名():

yield 数据

-- 调用:

for 变量名 in 函数名():

语句

  1. 说明:

-- 调用生成器函数将返回一个生成器对象,不执行函数体。

-- yield 翻译为”产生”或”生成”

  1. 执行过程:

(1) 调用生成器函数会自动创建迭代器对象。

(2) 调用迭代器对象的next()方法时才执行生成器函数。

(3) 每次执行到 yield 语句时返回数据,暂时离开。

(4) 待下次调用next()方法时继续从离开处继续执行。

  1. 原理:生成迭代器对象的大致规则如下

-- 将 yield 关键字以前的代码放在 next 方法中。

-- 将 yield 关键字后面的数据作为 next 方法的返回值。

"""
    MyRange 1.0 迭代器实现
    MyRange 2.0  yield实现
    MyRange 3.0  生成器实现必须会(浅出)
    range产生的海量数据不用担心撑爆内存,进来一次,排出一次
​
"""
​
# 实用价值:循环一次  计算一次  返回一次  以后工作当中就这么用
def my_range(stop):
    number = 0
    while number < stop:
        yield number
        number += 1
​
​
for number in my_range(5):
    print(number)  # 0 1 2 3 4
​
# 调用但不执行进入iter函数体,原因是有yield,
# 而是返回生成器对象,调试看对象
mr = my_range(5)
print(type(mr))  # <class 'generator'>
iterator = mr.__iter__()  # <class 'generator'>
print(type(iterator))
while True:
    try:
        item = iterator.__next__()
        print(item)  # 0  1   2  3  4
    except StopIteration:
        break
​
"""
伪代码:为了看清调试原理
class generator: # 生成器 = 可迭代对象+迭代器(核心)
    def __iter__(self): # 可迭代对象
        return self
​
    def __next__(self): # 迭代器
        index += 1
        return index
"""
​

"""
练习 1:定义函数,在列表中找出所有偶数 [43,43,54,56,76,87,98]
练习 2. 定义函数,在列表中找出所有字符串 [43,"悟空",True,56,"八戒",87.5,98]
"""
list01 = [43, 43, 54, 56, 76, 87, 98]
list02 = [43, "悟空", True, 56, "八戒", 87.5, 98]
​
# -- 传统思想:创建容器存储所有偶数,return容器
#定义好容器,一次性计算好返回计算结果,浪费性能----调试看
def get_evens1(list_number):
    result = []
    for item in list_number:
        if item % 2 == 0:
            result.append(item)
    return result
​
re = get_evens1(list01)
for item in re:
    print(item)
​
# -- 生成器思想:一个个推算偶数,yield 偶数
#一次一次迭代计算好返回计算结果,节约性能----调试看
def get_num(list1):
    index = 0
    while index < len(list01):
        if list01[index] % 2 == 0:
            yield list1[index]
        index += 1
​
​
​
# -- 生成器思想:一个个推算字符串,yield 字符串
def get_number(list1):
    index = 0
    while index < len(list01):
        if type(list1[index]) == str:
            yield list1[index]
        index += 1
​
​
for number in get_num(list01):
    print(number)
​
for number in get_number(list02):
    print(number)
"""
练习 1:定义函数,在列表中找出所有偶数 [43,43,54,56,76,87,98]
​
 -- 传统思想:创建容器存储所有偶数,return容器
 -- 生成器思想:一个个推算偶数,yield 偶数,优点是内存不崩溃,缺点是不存数据
                吃多少,排多少
"""
# 传统思想:
list01 = [43, 43, 54, 56, 76, 87, 98]
​
​
def oushu1(data):
    list02 = []
    for item in data:
        if item % 2 == 0:
            list02.append(item)
    return list02
​
​
print(oushu1(list01))
​
​
# 生成器思想1 (自己捣鼓的)
def oushu2(data):
    number = 0
    while number < len(data):
        if data[number] % 2 == 0:
            yield data[number]
        number += 1
​
​
for item in oushu2(list01):
    print(item)  # 0 1 2 3 4
​
​
# 生成器思想2
def get_evens2(list_number):
    for item in list_number:
        if item % 2 == 0:
            yield item
​
​
re = get_evens2(list01)  #这加断点,函数不上去,惰性,直接到下一行
for item in re:
    print(item)
​
"""
练习 2. 定义函数,在列表中找出所有数字 
[43,"悟空",True,56,"八戒",87.5,98]
​
结论(思想):函数有一个结果用return
           函数有多个结果用yelid
"""
# 传统思想:
list01 = [43, "悟空", True, 56, "八戒", 87.5, 98]
​
​
def get_num1(data):
    list02 = []
    for item in data:
        if type(item) in (int, float):
            list02.append(item)
    return list02
​
​
# 生成器思想
def get_num2(list_number):
    for item in list_number:
        if type(item) in (int, float):
            yield item
​
​
for item in get_num1(list01):  # 老式:函数体一顿循环 然后跳到for 又是一顿循环
    print(item)
for item in get_num2(list01):  # 新式:函数体与for轮流交替,上去下来,一上一下
    print(item)
​

内置生成器

枚举函数 enumerate

  1. 语法:

for 变量 in enumerate(可迭代对象):

语句

for 索引, 元素 in enumerate(可迭代对象):

语句

  1. 作用:遍历可迭代对象时,可以将索引与元素组合为一个元组。

"""
    内置生成器:不用担心性能,它是迭代思想
"""
list01 = [43, 43, 54, 56, 76]
​
# 以前
# 从头到尾读          -- 读取数据方便
for item in list01:
    print(item)
​
# 非从头到尾读        -- 有索引能修改
for i in range(len(list01)):
    if list01[i] % 2 == 0:
        list01[i] += 1
​
# 现在
# 读写数据时使用
list01 = [43, 43, 54, 56, 76]
for i, item in enumerate(list01):  # 拆包元组
    print(i, item)
​
for item in enumerate(list01):  # 不拆包元组
    print(item)#打印元组,很少用,因为不需要她两组合一起用
​
dict01 = {"a": "A", "b": "B"}
for i, key in enumerate(dict01):  # 拆包成key 与 i
    print(i, key, dict01[key])
​
​
​

"""
练习 1:将列表中所有奇数设置为 None
练习 2:将列表中所有偶数自增 1
"""
list01 = [43, 43, 54, 56, 76]
​
for i, item in enumerate(list01):
    if item % 2 == 1:
        list01[i] = None
        # item = None  只能读,不能改
print(list01)
​
list01 = [43, 43, 54, 56, 76]
for i, item in enumerate(list01):  # itere+回车自动生成
    if item % 2 == 0:
        list01[i] += 1
        # item = None  只能读,不能改
print(list01)
​

zip

  1. 语法:

for item in zip(可迭代对象 1, 可迭代对象 2….):

语句

  1. 作用:将多个可迭代对象中对应的元素组合成一个个元组,生成的元组个数由最小

的可迭代对象决定。

"""
    zip
​
    作用:将多个可迭代对象中对应的元素组合成一个个元组,
     生成的元组个数由最小 的可迭代对象决定,木桶短板原则。
"""
list_name = ["gsx", "wzg", "zwj"]
list_age = [22, 26]
​
# for 变量 in zip(可迭代对象1,可迭代对象2)
for item in zip(list_name, list_age):
    print(item)
#('gsx', 22)
#('wzg', 26)
​
​
# 应用:矩阵转置 其中3.0一句话到位
map = [
    [2, 0, 0, 2],
    [4, 2, 0, 2],
    [2, 4, 2, 4],
    [0, 4, 0, 4]
]
​
# 1.0
# new_map = []
# for item in zip(map[0], map[1], map[2], map[3]):#手动拆开
#     new_map.append(list(item))
# print(new_map)
​
# 2.0
# new_map = []
# for item in zip(*map):#自动拆开:实参拆开
#     new_map.append(list(item))
​
# 3.0 列表推导式
new_map = [list(item) for item in zip(*map)]
print(new_map)
​

"""
    练习:使用学生列表封装以下三个列表中数据
    list_student_name = ["悟空", "八戒", "白骨精"]
    list_student_age = [28, 25, 36]
    list_student_sex = ["男", "男", "女"]
"""
​
​
# 1.0 添加数据需要修改代码,不灵活
class Student:
    def __init__(self, name="", age=0, sex=""):
        self.name = name
        self.age = age
        self.sex = sex
​
    def __str__(self):
        return f"{self.name},{self.age},{self.sex}"
​
​
# list_student_name = ["悟空", "八戒", "白骨精"]
# list_student_age = [28, 25, 36]
# list_student_sex = ["男", "男", "女"]
# list_student = []
# for item in zip(list_student_name, list_student_age, list_student_sex):
#     stu = Student(item[0],item[1],item[2])
#     list_student.append(stu)
# print(list_student)
​
​
# 2.0 添加数据不需要修改代码,灵活
list_datas = [
    ["悟空", "八戒", "白骨精"],
    [28, 25, 36],
    ["男", "男", "女"]
]
# list_student = []
# for data in zip(*list_datas):#自动拆开每一个元素,依次取每个元素的索引对应值
#     stu = Student(*data)#自动拆开赋值给实例变量
#     list_student.append(stu)
​
# 3.0推导式实现
list_student = [Student(*data) for data in zip(*list_datas)]
print(list_student)
​

# 深度体会生成器价值
class Employee:
    def __init__(self, eid, did, name, money):
        self.eid = eid
        self.did = did
        self.name = name
        self.money = money
​
​
list_employees = [
    Employee(1001, 9002, "师父", 60000),
    Employee(1002, 9001, "孙悟空", 50000),
    Employee(1003, 9002, "猪八戒", 20000),
    Employee(1004, 9001, "沙僧", 30000),
    Employee(1005, 9001, "小白龙", 15000),
]
​
​
# 练习1:定义函数,在员工列表中查找did是9001的所有员工:返回多个
def find_emp_did():
    for item in list_employees:
        if item.did == 9001:
            yield item
​
​
# 调用函数不执行函数体,返回生成器对象(推算数据)
result = find_emp_did()
for item in result:
    print(item.__dict__)
​
​
# 练习2:定义函数,在员工列表中查找薪资大于20000的所有员工:返回多个
def find_emp_money():
    for item in list_employees:
        if item.money > 20000:
            yield item
​
​
result = find_emp_money()
for item in result:
    print(item.__dict__)
​
​
# 练习3:定义函数,在员工列表中查找eid是1003的员工  :返回一个 用return
def find_emp_eid():
    for item in list_employees:
        if item.eid == 1003:
            return item
​
​
emp = find_emp_eid()
print(emp.__dict__)
​
# 缺点1:生成器的对象只能使用(for)一次,因为用next到最后了
# result = find_emp_money()
# for emp in result:
#     print(emp.__dict__)
# for emp in result: # 不执行,调试看看
#     print(emp.__dict__)
​
# 缺点2:不能定位元素(不支持索引与切片),只能for 然后一个个next
# print(result[1])
print(type(find_emp_money()))  # <class 'generator'>
​
# 解决:将生成器转换为容器,就不用使用for了啊,非常灵活的用,
# 但缺点是列表占内存,for不占内存,但只能next一个一个用
list_result = list(find_emp_money())
print(list_result)
​
​
# 练习4:定义函数,在员工列表中查找所有员工的姓名
def find_employees_name():
    for item in list_employees:
        yield item.name
​
​
re = find_employees_name()
# 只产生re一个生成器对象,不可以for
# 两次,除非调用函数再产生个re给另外一个for用
list_result = list(re)
print(list_result)
​

生成器表达式

  1. 定义:用推导式形式创建生成器对象。

  1. 语法:变量 = ( 表达式 for 变量 in 可迭代对象 [if 真值表达式] )

"""
    列表推导式
        列表 = [对变量操作 for 变量 in 可迭代对象]
        列表 = [对变量操作 for 变量 in 可迭代对象 if 条件]
        优点:
            可以定位(索引切片)
            反复使用
        缺点:
            占用内存
​
    生成器表达式
        生成器 = (对变量操作 for 变量 in 可迭代对象)
        生成器 = (对变量操作 for 变量 in 可迭代对象 if 条件)
        优点:
            节省内存
        缺点:
            不可以定位(索引切片)
            不反复使用
"""
list01 = [432, 5, 54, 6, 76, 87]
#     列表推导式  需求:将大于10的元素存储新列表
# 调试上上上....下下下......
list02 = [item for item in list01 if item > 10]
for item in list02:
    print(item)
​
# 生成器表达式:调试上下上下上下......
generator02 = (item for item in list01 if item > 10)
for item in generator02:
    print(item)
​
"""
生成器表现形式1:推导式
         语法:变量 = ( 表达式 for 变量 in 可迭代对象 [if 真值表达式] )
         
生成器表现形式2:普通形式      
       -- 创建: 
       def 函数名(): …
            yield 数据 …
       -- 调用: 
       for 变量名 in 函数名():
            语句
            
生成器核心:计算一次,返回一次,执行一次
"""

"""
    练习1:使用生成器表达式在列表中获取所有字符串.
    list01 = [43, "a", 5, True, 6, 7, 89, 9, "b"]
    练习2:在列表中获取所有整数,并计算它的平方.
"""
list01 = [43, "a", 5, True, 6, 7, 89, 9, "b"]
all_str = (item for item in list01 if type(item) == str)
for item in all_str:
    print(item)
​
all_number = (item ** 2 for item in list01 if type(item) == int)
for item in all_number:
    print(item)

    小结 - 生成器
        生成器函数
            def 函数名():
                ...
                yield 数据
                ...
​
            for item in 函数名():
                ...
​
            适用性:函数有多个结果使用yield
            如果需要反复使用,定位数据,使用下列调用方式:
                变量 = 容器(函数名())
​
​
        生成器表达式
            当使用列表推导式时,如果不需要反复使用且定位数据,
            应该改为生成器表达式
​
        笔试题:
            请简述生成器与迭代器的关系?
                生成器本质就是迭代器+可迭代对象
                当使用生成器时,就是重复调用__next__函数,计算一次返回一次数据,
                不将所有数据存储在内存中.
​

class Commodity:
    def __init__(self, cid, name="", price=0):
        self.cid = cid
        self.name = name
        self.price = price
​
​
list_commodity_infos = [
    Commodity(1001, "屠龙刀", 10000),
    Commodity(1002, "倚天剑", 10000),
    Commodity(1003, "金箍棒", 52100),
    Commodity(1004, "口罩", 20),
    Commodity(1005, "酒精", 30),
]
​
​
# 要求:使用生成器函数(反复使用)和生成器表达式完成(用一次)
# 练习1:查找商品编号小于1003的所有商品
​
# 1
def find_cmd_cid():
    for item in list_commodity_infos:
        if item.cid < 1003:
            yield item
​
​
# 调用函数不执行函数体,返回生成器对象(推算数据)
for item in find_cmd_cid():
    print(item.__dict__)
​
# 2
generator02 = (item for item in list_commodity_infos if item.cid < 1003)  # 变成小括号
for item in generator02:
    print(item.__dict__)
​
​
# 练习2:查找商品名称大于2个字的所有商品
# 1
def find_emp_name():
    for item in list_commodity_infos:
        if len(item.name) > 2:
            yield item
​
​
# 调用函数不执行函数体,返回生成器对象(推算数据)
for item in find_emp_name():
    print(item.__dict__)
​
# 2
generator02 = (item for item in list_commodity_infos if len(item.name) > 2)  # 变成小括号
for item in generator02:
    print(item.__dict__)
​
​
# 练习3:查找商品单价大于10000元的所有商品名称
# 1
def get_commodity_price():
    for cmd in list_commodity_infos:
        if cmd.price > 10000:
            yield cmd.name
​
​
for item in get_commodity_price():
    print(item)
​
# 2
commodity_names = (cmd.name for cmd in list_commodity_infos if cmd.price > 10000)
for item in commodity_names:
    print(item)
​
​
# 练习4:查找单价最便宜的商品信息(自定义函数)
def get_min_by_price():
    min_value = list_commodity_infos[0]
    for i in range(1, len(list_commodity_infos)):
        if min_value.price > list_commodity_infos[i].price:
            min_value = list_commodity_infos[i]
    return min_value
​
​
min_value = get_min_by_price()
print(min_value.__dict__)
​
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dpq666dpq666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值