2021-04-23 第一阶段day17

day17

一、迭代

1、迭代器对象iterator

(1)定义

定义:可以被next()函数调用并返回下一个值的对象。
需求:迭代自定义对象。

(2)语法

class 迭代器类名:
    def init(self, 聚合对象):
        self.聚合对象= 聚合对象
    def next(self):
         if 没有元素:
            raise StopIteration
        return 聚合对象元素

说明:聚合对象通常是容器对象。
作用:使用者只需通过一种方式,便可简洁明了的获取聚合对象中各个元素,而又无需了解其内部结构。

(3)演示

class StudentIterator:  # 学生迭代器(可迭代对象)
    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 StudentController:  # 学生控制器
    def __init__(self):
        self.__list_student = []

    def add_student(self, stu):
        self.__list_student.append(stu)

    def __iter__(self):
        return StudentIterator(self.__list_student)

controller = StudentController()
controller.add_student("赵敏")
controller.add_student("张无忌")
controller.add_student("周芷若")

for item in controller:
    print(item)

# iterator = controller.__iter__()
# while True:
#     try:
#         item = iterator.__next__()
#         print(item)
#     except StopIteration:
#         break

(4)迭代器(过渡)

class StudentController:  # 学生控制器
    def __init__(self):
        self.__list_student = []

    def add_student(self, stu):
        self.__list_student.append(stu)

    def __iter__(self):
        # 产生迭代器代码的大致思想:
        # 1、将yield之前的代码存到__next__函数中
        # 2、将yield之后的数据作为__next__返回值
        index = 0
        yield self.__list_student[index]       # yield:产生
        index += 1
        yield self.__list_student[index]
        index += 1
        yield self.__list_student[index]

controller = StudentController()
controller.add_student("赵敏")
controller.add_student("下基层")
controller.add_student("跟他说")

# for item in controller:
#     print(item)

iterator = controller.__iter__()
while True:
    try:
        item = iterator.__next__()
        print(item)
    except StopIteration:
        break

二、生成器generator

1、生成器函数

(1)语法

#创建
def 函数名():
            yield 数据
#调用
for 变量名 in 函数名():
            语句

(2)说明

调用生成器函数将返回一个生成器对象,不执行函数体
yield翻译为”产生”或”生成”。

(3)执行过程

a. 调用生成器函数会自动创建迭代器对象。
b. 调用迭代器对象的next()方法时才执行生成器函数。
c. 每次执行到yield语句时返回数据,暂时离开。
d. 待下次调用next()方法时继续从离开处继续执行。

(4)演示

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

(5)应用

函数向外返回多个结果,使用yield
函数向外返回单个结果,使用return

'''
	需求:定义函数,在list01中查找所有奇数
'''
list01 = [43,4,54,56,67,7,87]

# --传统思想:创建容器存储所有结果
# 缺点:占用空间过多
def find_odd():
    list_result = []
    for number in list01:
        if number % 2 :
            list_result.append(number)
    return list_result
result = find_odd()
for item in result:
    print(item)

# --生成器思想:循环一次,计算一次,返回一次
# 优点:几乎不占内存
def find_odds():
    for number in list01:
        if number % 2:
            yield number

# 调用函数,返回值是生成器对象(迭代器__next__),负责推算数据
result = find_odds()
for item in result:
    print(item)

2、 内置生成器

(1)函数enumerate

作用:在遍历容器时,同时获取元素和其索引,将索引与元素组合为一个元组。
缺点:不能跳着走,不够灵活。

list01 = [54,45,54,6,7,8]
# 索引,元素  快捷键:itere + 回车
for i,item in enumerate(list01): # 可读可改
    if item > 10:
        list01[i] = 0

(2)函数zip

作用:将两个容器索引相同的值压缩成一个元组。
语法:

生成器 = zip(可迭代对象1,可迭代对象2)
for 元组 in 生成器:

list01 = ["张无忌","赵敏","周芷若","金毛狮王"]
list02 = [101,102,103,104]
for item in zip(list01,list02):
    print(item)
map = [
    [2, 0, 0, 2],
    [2, 0, 2, 0],
    [2, 2, 2, 2],
    [4, 0, 2, 2]
]
# new_map = []
# for item in zip(map[0],map[1],map[2],map[3]):
#     new_map.append(list(item))
# print(new_map)

# new_map = []
# for item in zip(*map):
#     new_map.append(list(item))

new_map = [list(item) for item in zip(*map)]
print(new_map)

3、生成器表达式

(1)与列表表达式的区别

语法 优点 缺点
生成器表达式 生成器 = (变量 for 变量 in 可迭代对象 if 条件) 节省内存 元素只读,只能使用一次,不支持索引切片
列表表达式 列表表达式= [变量 for 变量 in 可迭代对象 if 条件] 元素可读可写,可以反复使用,使用索引切片 占用内存过多

(2)演示

list01 = [31,432,65,2,5,1]
# result = [item for item in list01 if item % 2]
result = (item for item in list01 if item % 2)
for item in result:
    print(item)
上一篇:达内C语言数据结构(DAY17)


下一篇:记录内网渗透学习进程--DAY17