本章所讲内容:
1、可迭代对象
2、迭代器
3、生成器
我们已经知道可以对list、tuple、str等类型的数据使⽤for...in...的循环语法,其中依次拿到数据进⾏使⽤,我们把这样的过程称为遍历,也叫迭代。
但是,是否所有的数据类型都可以放到for...in...的语句中,然后让for...in...每次从中取出⼀条数据供我们使⽤,让我们迭代吗?
案例:(对一个数字进行遍历)
for i in 100:
print(i)
运行结果如下:
Traceback (most recent call last):
File "E:/xuegod_code/1_6_函数高阶知识点/test.py", line 14, in
for i in 100:
TypeError: 'int' object is not iterable
很明显我们的数字类型的数据是不可迭代的!那我们该如何判断我们的数据是可迭代的呢?
7.1.1 isinstance方法
如何判断⼀个对象是否可以迭代可以使⽤isinstance()这个方法,首先我们导入内置的方法collections中的Iterable这个方法,以方便我们进一步判断。
from collections import Iterable
print(isinstance('abc',Iterable))
print(isinstance([1,2,3],Iterable))
print(isinstance({1,2,3},Iterable))
print(isinstance({"a":1},Iterable))
print(isinstance(1,Iterable))
运行结果如下:
True
True
True
True
False
遍历的是可迭代对象:
for item in Iterable 循环的本质就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束。
遍历的是迭代器:
for item in Iterator 循环的迭代器,不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束。
什么是迭代器?
迭代器是访问可迭代对象的工具;
迭代器是指用iter(obj) 函数返回的对象(实例);
迭代器可以用next(it) 函数获取可迭代对象的数据;
迭代器函数iter和next
iter(iterable) 从可迭代对象中返回一个迭代器,iterable 必须是能提供一个迭代器的对象
next(iterator) 从迭代器iterator中获取下一个记录,如果无法获取下一条记录,则触发StopIteration异常
说明:
迭代器只能向前取值,不会后退
用iter函数可以返回一个可迭代对象的迭代器
好处:
迭代器不要求你事先准备好整个迭代过程中所有的元素。仅仅是在迭代至某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合。
作用:
迭代器对象能用next函数获取下一个元素.
示例:
L = [2, 3, 5, 7]
it = iter(L) # 用L对象返回能访问L的迭代器, it绑定迭代器
next(it) # 2
next(it) # 3
next(it) # 5
next(it) # 7
next(it) # StopIteration 通知(没有数据)
it = iter(range(1, 10, 3))
next(it) # 1
next(it) # 4
next(it) # 7
next(it) # StopIteration
用迭代器访问可迭代对象示例:
L = [2, 3, 5, 7]
for x in L:
print(x)
else:
print('循环结束')
示例二:
it = iter(L) # 从L中获取一个迭代器
while True:
try:
x = next(it)
print(x)
except StopIteration:
print("循环结束")
break
运行结果如下:
2
3
5
7
循环结束
2
3
5
7
循环结束
练习:
有一个集合:s = {'唐僧', '悟空', '八戒', '沙僧'}
用 for语句来遍历所有元素如下:
for x in s:
print(x)
else:
print('遍历结束')
请将上面的for语句改写为 while语句和迭代器实现?
s = {'唐僧', '悟空', '八戒', '沙僧'}
L = iter(s)
n = 0
while n < len(s):
# next(L)
print(next(L))
n += 1
else:
print('遍历结束')
7.3 生成器
7.3.1 生成器的介绍
什么是生成器?
生成器是能够动态提供数据的对象,生成器对象也是可迭代对象(实例),在这里可以认为生成器其实就是迭代器的一种。
生成器有两种:
1. 生成器函数
2. 生成器表达式
生成器函数的定义
含有yield语句的函数是生成器函数,此函数被调用将返回一个生成器对象
yield 翻译为(产生或生成)
yield 语句
语法:
yield 表达式
说明:
yield 用于 def 函数中,目的是将此函数作用生成器函数使用
yield 用来生成数据,供迭代器的next(it) 函数使用
示例:
# 此示例示意生成器函数的定义方法和用法
def my_yield():
print("即将生成2")
yield 2
print("即将生成3")
yield 3
print("即将生成5")
yield 5
print("即将生成7")
yield 7
print("生成结束")
gen = my_yield() # gen 绑定一个生成器对象
it = iter(gen) # 用生成器返回一个迭代器
# 从迭代器获取一个数据(此时生成器函数才开始执行)
print(next(it))
生成器函数说明:
生成器函数的调用将返回一个生成器对象,生成器对象是一个可迭代对象
生成器表达式:
语法:
(表达式 for 变量 in 可迭代对象 [if 真值表达式 ])
说明:
if 子句可以省略
作用:
用推导式的形式创建一个新的生成器
示例:
gen = (x ** 2 for x in range(1, 5))
it = iter(gen)
next(it) # 1
next(it) # 4
next(it) # 9
next(it) # 16
next(it) # StopIteration
练习:
已知有一个列表L
L = [2, 3, 5, 7]
用生成器表达式从此列表中拿到数,生成列表中数据的平方
gen = ...... # 此处用生成器表达式实现
L2 = list(gen) # L2 = [4, 9, 25, 49]
思考:
L = [2, 3, 5, 7]
L2 = [x ** 2 for x in L] # 列表推导式
it = iter(L2)
print(next(it)) # 4
L[1] = 10
print(next(it)) # 9
L = [2, 3, 5, 7]
G3 = (x ** 2 for x in L) # 生成器表达式
it = iter(G3)
print(next(it)) # 4
L[1] = 10
print(next(it)) # 100
7.3.2 迭代工具函数
迭代工具函数的作用是生成一个个性化的可迭代对象
zip(iter1[, iter2[, ...]]) 返回一个zip对象,此对象用于生成元组,此元组的个数由最小的可迭代对象决定
enumerate(iterable[, start]) 生成带索引的枚举对象,返回迭代类型为索引-值对(index-value对),默认索引从零开始,也可以用start指定
示例:
numbers = [10086, 10000, 10010, 9558]
names = ['中国移动', '中国电信', '中国联通']
for t in zip(numbers, names):
print(t)
for x, y in zip(numbers, names):
print(y, '的客服电话是:', x)
x, y = (10086, '中国移动') # 序列赋值
zip方法重写:
def myzip(iter1, iter2):
it1=iter(iter1) # 拿出一个迭代器
it2=iter(iter2)
while True:
a=next(it1)
b=next(it2)
yield (a, b)
for t in myzip(numbers, names): # 能实现与zip同样的功能
print(t)
前面作业的答案:重写zip方法!
def myzip(*args):
all_list = []
for i in range(len(args)):
all_list.append(args[i])
sort_list = sorted(all_list,key=lambda x:len(x))
min_list_longth = len(sort_list[0])
a_list = []
for a in range(min_list_longth):#0,1,2
a = [args[j][a] for j in range(len(args))]
a_list.append(a)
print(a_list)
myzip([1,2,3],[4,2],[1,3,4,5],[1,2,3,4,5,6])
enumerate 示例:
names = ['中国移动', '中国电信', '中国联通']
for t in enumerate(names):
print(t)
enumerate 实现方法示例:
def myenum(iterable):
it = iter(iterable)
i = 0
while True:
a = next(it)
yield (i, a)
i += 1
总结:
1、可迭代对象
2、迭代器
3、生成器