python基础三_04_可迭代对象_生成器_迭代器

python基础三_04_可迭代对象_迭代器_生成器

导读:
本文主要记录自己学习python3基础中可迭代对象、迭代器和生成器的要点知识和例子;仅供自己梳理。

一、可迭代对象

1.什么是可迭代对象?

可迭代对象就是:实现了迭代器协议的对象

哈哈哈,相信看完这个概念你还是不知道什么是可迭代对象。

我们已经知道可以对list、tuple、str等类型的数据使用for…in…的循环语法,其中依次拿到数据进行使用,我们把这样的过程称为遍历,也叫迭代。那么,是否所有的数据类型都可以放到for…in…语句中迭代?
for i in 10:
    print(i)

在这里插入图片描述

很明显我们的数字类型的数据是不可迭代的!但是如果改成 range(10),就可以迭代。那我们该如何判断我们的数据是可迭代的呢?

2.isinstance方法

# 判断你的基本数据类型可否迭代
from collections.abc import Iterable

# 判断字符串'abc'是否为可迭代对象
print(isinstance('abc',Iterable))

# 判断列表[1,2,3]是否为可迭代对象
print(isinstance([1,2,3],Iterable))

# 判断元组((1,2,3)是否为可迭代对象
print(isinstance((1,2,3),Iterable))

# 判断字典{'name':'wdxq'}是否为可迭代对象
print(isinstance({'name':'ydxq'},Iterable))

# 判断int整数1是否为可迭代对象
print(isinstance(1,Iterable))

在这里插入图片描述

3.for循环的本质

遍历的是可迭代对象:
for item in Iterable 循环的本质就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束。
遍历的是迭代器:
for item in Iterator 循环的迭代器,不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束。

在这里插入图片描述

我们都知道,能够用for循环迭代的都是可迭代对象。那么for循环的本质是什么呢?它是怎么来迭代的?
data = '123456'
# iter()可将data转换为迭代器
it = iter(data)

# 访问迭代器中的数据
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))

在这里插入图片描述

只有6个数,如果再打印next呢?那就会报StopIteration异常

print(next(it))

那为何for循环的时候没报异常?如下:
data = '123456'
# iter()可将data转换为迭代器
it = iter(data)

# 访问迭代器中的数据
print(next(it))
print(next(it))
print(next(it))
# 
for i in it:
    print(i)

在这里插入图片描述

这个问题我们往下看。

二、迭代器

1.什么是迭代器?

迭代器是访问可迭代对象的工具;
迭代器是指用iter() 函数返回的对象(实例);
迭代器可以用next() 函数获取可迭代对象的数据;

2.迭代器函数iter和next

iter(iterable) 从可迭代对象中返回一个迭代器,iterable 必须是能提供一个迭代器的对象
next(iterator) 从迭代器iterator中获取下一个记录,如果无法获取下一条记录,则触发StopIteration异常

在这里插入图片描述

说明:
迭代器只能向前取值,不会后退
用iter函数可以返回一个可迭代对象的迭代器
作用:
迭代器对象能用next函数获取下一个元素.
好处:
迭代器不要求你事先准备好整个迭代过程中所有的元素。仅仅是在迭代至某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合。
3.for循环的本质用while来展示
# L是一个可迭代对象
L = [9,5,2,7]
for x in L:
    print(x)
else:
    print('循环结束')
try-except是python抓取异常的写法
# L是一个可迭代对象
L = [9,5,2,7]
# 使用iter()函数把可迭代对象变成迭代器
it = iter(L)
#
while True:
    # try关键字里面放入可能出错的代码
    try:
        # 使用next()函数获取迭代器中数据
        print(next(it))
    # 如果出现错误,就执行except里面的语句块
    except StopIteration:
        print('循环结束')
        break

三、生成器

1.什么是生成器?

生成器是能够动态提供数据的对象,生成器对象也是可迭代对象(实例),在这里可以认为生成器其实就是迭代器的一种。

2.生成器有两种:生成器函数和生成器表达式

(1).生成器函数的定义
含有yield语句的函数是生成器函数,此函数被调用将返回一个生成器对象

在这里插入图片描述

yield 语句说明:
yield 用于 def 函数中,目的是将此函数作用生成器函数使用
yield 用来生成数据,供迭代器的next(it) 函数使用
# 此示例示意生成器函数的定义方法和用法
def my_yield():
    print('即将生成9')
    yield 9
    print('即将生成5')
    yield 5
    print('即将生成2')
    yield 2
    print('即将生成7')
    yield 7
    print('生成结束')

gen = my_yield()
# 生成器函数的调用将返回一个生成器对象,生成器对象是一个可迭代对象
print(gen)
# <generator object my_yield at 0x000002A9E02479C8>
#print(list(gen))

print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
(2).生成器表达式
语法: (表达式 for 变量 in 可迭代对象 [if 真值表达式 ])
说明:if 子句可以省略
作用:用推导式的形式创建一个新的生成器
# 生成器表达式 类似于列表推导式
gen = (i for i in range(1,5))
#
print(next(gen))
#
for j in gen:
    print(j)

四、迭代工具函数

迭代工具函数的作用是生成一个个性化的可迭代对象

1.zip方法

zip(iter1[, iter2[, …]]) 返回一个zip对象,此对象用于生成元组,此元组的个数由最小的可迭代对象决定
numbers = [10086, 10000, 10010, 9558]
names = ['中国移动', '中国电信', '中国联通']
for t in zip(numbers,names):
    print(t)
# 序列赋值 
for x,y in zip(numbers,names):
    print(y,'客服电话是:',x)

在这里插入图片描述

2.enumerate方法

enumerate(iterable[, start]) 生成带索引的枚举对象,返回迭代类型为索引-值对(index-value对),默认索引从零开始,也可以用start指定
def my_enum(iterable,i=0):
    it = iter(iterable)
    i = i
    n = 0
    while n < len(iterable):
        a = next(it)
        yield (i,a)
        i+=1
        n += 1
print(list(my_enum(names,1)))

在这里插入图片描述

3.zip方法的重写

法一
numbers = [10086,10000,10010,9558]
names = ['中国移动','中国电信','中国联通']

def myzip(iter1,iter2):
    it1 = iter(iter1)
    it2 = iter(iter2)

    try:
        while True:
            a = next(it1)
            b = next(it2)
            yield (a,b)
    except:
        pass

for t in myzip(names,numbers):
    print(t)
法二
def my_zip(*args):
    #print(*args)
    # 1.列表元素长度从小到大排序,key按照x进行排序,x是列表元素长度
    sort_list = sorted(args,key=lambda x:len(x))
    #print(sort_list)
    # 2.获取最小列表长度,两种方法
    # min_list_logth = len(sort_list[0])
    min_logth = min(args,key=lambda x:len(x))
    #print(min_logth)
    #print(len(min_logth))
    data = []
    for i in range(len(min_logth)):
        b = [args[j][i] for j in range(len(args))]
        # i = 0 时,j = 0,1,2,3    args[j][i]:args[0][0],args[1][0],args[2][0],args[3][0]
        # i = 1 时,j = 0,1,2,3    args[j][i]:args[0][1],args[1][1],args[2][1],args[3][1]
        # i = 2 时,j = 0,1,2,3    args[j][i]:args[0][2],args[1][2],args[2][2],args[3][2]
        data.append(b)
    print(data)


my_zip([1,2,3],[4,2,2],[1,2,3,4,5],[1,2,3])

# 用到的方法
# sorted()
# min()
# len()

五、参考链接

如何更好地理解Python迭代器和生成器?

Python3 迭代器与生成器

python 生成器和迭代器有这篇就够了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值