迭代器Iterator
什么是迭代器
迭代器是访问可迭代对象的工具
迭代器是指用iter(obj) 函数返回的对象(实例)
迭代器可以用next(it) 函数获取可迭代对象的数据
迭代器函数 iter和next
iter(iterable) 从可迭代对象中返回一个迭代器,iterable 必须是能提供一个迭代器的对象
next(iterator) 从迭代器iterator中获取下一个记录,如果无法获取下一条记录,则触发StopIterator异常
说明:
1. 迭代器只能往前取值,不会后退
2. 用iter函数可以返回一个可迭代对象的迭代器
示例:
L = [1, 3, 5, 7]
it = iter(L) # 让L提供一个能访问自己的迭代器
next(it) # 1 从迭代器中取值,让迭代器去获取L中的一个元素
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) # 2 3 5 6
# 以下用迭代器来访问L列表中的元素
L = [2, 3, 5, 7]
it = iter(L) # 先拿到迭代器用iter绑定
while True:
x = next(it) # 获取一个数据并绑定到x
print(x) # 2 3 5 7
生成器 Generator
什么是生成器
生成器是能够动态提供数据的对象,生成器对象也是可迭代对象(实例)
生成器有两种
生成器函数
生成器表达式
生成器函数的定义:
含有yield语句的函数是生成器函数,此函数被调用将返回一个生成器对象
yield翻译为产生(或生成)
yield 语句
语法:
yield 表达式
说明:
yield 用于 def 函数中,目的是将此函数作用生成器函数使用
yield 用来生成数据,供迭代器和next(it) 函数使用
示例:
# 此示例示意含有yield语句的函数为生成器函数,及用yield生成整数
def myyield():
yield 2
yield 3
yield 5
yield 7
print("生成器生成结束")
for x in myyield():
print(x) # 2 3 5 7
# 调用生成器函数来创建一个生成器,此生成器能生成
# 2 3 5 7 这样四个数
gen = myyield()
it = iter(gen) # 用生成器拿到对应的迭代器
print(next(it)) # 2 访问迭代器
print(next(it)) # 3 访问迭代器
print(next(it)) # 5 访问迭代器
# 此示例示意含有yield语句的生成器函数的调用顺序
# 生成器函数只有在next(it) 函数调用时才会执行,且遇到yield后
# 返回相应的值给next(it)函数
def myyield():
print("即将生成2")
yield 2
print("即将生成3")
yield 3
print("即将生成5")
yield 5
print("即将生成7")
yield 7
print("生成器生成结束")
gen = myyield()
it = iter(gen)
print(next(it)) # 2
print(next(it)) # 3
print(next(it)) # 5
print(next(it)) # 7
print(next(it)) # StopIteration
# 此示列示意用生成器函数生成从0开始到n结束的一系列的整数
def myinteger(n):
i = 0
while i < n:
yield i
i += 1
for x in myinteger(30000000000):
print(x) # 0 1 2
L = [x for x in myinteger(100) if x % 2 == 1]
print("L =", L)
生成器函数说明:
生成器函数的调用将返回一个生成器对象,生成器对象是一个可迭代对象,通常用来动态生成数据
生成器函数调用 return 语句会触发一个StopIterator异常
生成器表达式
语法:
(表达式 for 变量 in 可迭代对象 [if 真值表达式])
作用:
用推导式形式创建一个新的生成器
说明:
if 子句可以省略
示例:
gen = (x**2 for x in range(1, 5))
it = iter(gen)
print(next(it)) # 1
print(next(it)) # 4
print(next(it)) # 9
print(next(it)) # 16
print(next(it)) # StopIteration
生成器表达式和列表推导式的区别:
示例:
L = [2, 3, 5, 7]
L2 = [x ** 2 + 1 for x in L]
it = iter(L2)
print(next(it)) # 5
L[1] = 30
print(next(it)) # 10
# 以下是生成器表达式
L = [2, 3, 5, 7]
gen = (x ** 2 + 1 for x in L)
it = iter(gen)
print(next(it)) # 5
L[1] = 30
print(next(it)) # 901
生成器表达式是现用现生成,列表推导式是一次性生成静态数据
迭代工具函数:
作用是生成一个个性化的可迭代对象
函数:
zip(iter1 [, iter2[....]]) 返回一个zip对象,此对象用于生成元组,此元组的每个数据来源于参数中的可迭代对象,当最小的可迭代对象不再提供数据时迭代结束
enumerate(iterable [, start]) 生成带索引的枚举对象,返回的迭代类型为索引-值对(index-value)对,默认索引从零开始,也可以用start指定
zip示例:
numbers = [10086, 10000, 10010, 95588]
names = ['中国移动', '中国电信', '中国联通']
for t in zi p(numbers, names):
print(t)
for No, number, name in zip(range(1, 100),
numbers,
names):
print("序号",No, name, '的客服电话是:', number)
示例:
def myzip(iter1, iter2):
it1 = iter(iter1) # 拿到两个对象的迭代器
it2 = iter(iter2)
while True:
try:
t = (next(it1), next(it2)) # StopIteration
yield t
except StopIteration:
break
numbers = [10086, 10000, 10010, 95588]
names = ['中国移动', '中国电信', '中国联通']
for t in myzip(numbers, names):
print(t)
enumerate示例:
names = ['中国移动', '中国电信', '中国联通']
for t in enumerate(names):
print(t) #(0, '中国移动')(1, '中国电信')(2, '中国联通')
for t in enumerate(names, 101):
print(t) #(101, '中国移动')(102, '中国电信')
课后习题:
1. 用生成器函数,生成素数,给出起始值begin和终止值 end, 生成begin到end范围内的素数
如:
def prime(begin, end):
...
L=[x for x in prime(10, 20)] #L=[11,13,17,19]
2. 写一个生成器函数myxrange([start, ], stop[, step]) 来生成一系列整数
要求:
myxrange功能与range功能相同(不允许调用range函数)
用自己写的myxrange函数结合生成器表达式求1~10内奇数的平方和
想要看更多的课程请微信关注SkrEric的编程课堂