特点
- 访问集合元素的一种方式。
- 迭代器是一个可以记住遍历的位置的对象。
- 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
- 迭代器有两个基本的方法:iter() 和 next()。
- 列表(list),元组(tuple),字典(dict),集合(set),字符串(str)都可用于创建迭代器列表
- 文件也是一个迭代器,可以使用next方法逐行读取
- 迭代到结尾会抛出 StopIteration异常
iter()、next()
使用iter方法创建迭代器对象,使用next由前向后访问元素
def ex1():
lst = [1, 2, 3, 4]
iterList = iter(lst)
print(next(iterList)) # 1
print(next(iterList)) # 2
print(next(iterList)) # 3
# ex1()
用法
for循环
def ex2():
lst = [1, 2, 3, 4]
iterList = iter(lst)
print(next(iterList)) # 1
for i in iterList:
print("now", i) #会接着上个迭代器进行访问
# print(next(iterList)) # 抛出异常
# 相当于
# for i in range(4):
# print("now", next(iterList))
创建迭代器
类迭代器
需要实现self.__iter__方法和self.__next__方法,从而使类成为一个迭代器,能够调用iter()和next()方法
class MyIter:
def __init__(self, value):
self.num = value
self.value = 0
# 设置初始值\状态
def __iter__(self):
self.value = self.num
return self
def __next__(self):
temp = self.value
self.value += 1
return temp
def testMyIter():
iter_test = MyIter(4)
iterator = iter(iter_test)
print(next(iterator))
print(next(iterator))
print(next(iterator))
# testMyIter()
反向迭代
- 列表、元组、字典等,可reversed函数可以进行反向迭代
- 类迭代器需要实现__reversed__方法才能反向迭代
- 也可以将数据填充到一个列表然后反向迭代
def reversedTest():
lst = [1, 2, 3, 4]
for i in lst:
print(i)
print("=="*20)
for i in reversed(lst):
print(i)
# reversedTest()
生成器
使用yield表示生成的对象
def countFrom(d):
print("开始从%d计数"%d)
while d > 0:
yield d
d -= 1
print("计数完成!")
def testCountFrom():
generator = countFrom(10)
for i in generator:
print(i)
# next(generator) #抛出StopIteration异常
print(generator) # 生成器类型
# testCountFrom()
切片
特点
- 需要import itertools中的islice()
- islice() 会消耗掉传入的迭代器中的数据,
如果islice消耗完全部数据后再next后者islice相同元素会报错 - islice(iterator, start, None) = iterator[start:]
islice(iterator, None, end) = iterator[:end] - islice(iterator, start, end) = iterator[start:end]
from itertools import islice
def ex5():
d = 0
while d < 20:
yield d
d += 1
def test_1Ex5():
generator = ex5()
test_generator = generator
# 报错 TypeError: 'generator' object is not subscriptable
# test_generator = generator[1:5]
# test_generator = islice(generator, 1, 5) # 1, 2, 3, 4
for i in test_generator:
print(i)
next(test_generator) #报错
# test_1Ex5()
排列、组合
- from itertools import permutations
- 用法
from itertools import permutations
from itertools import combinations
from itertools import combinations_with_replacement
def ex6():
items = ['a', 'b', 'c', 'd']
length = 2
print("="*20 + "排列" + "="*20)
for sequence in permutations(items, length):
print(sequence)
print("=" * 20 + "组合" + "=" * 20)
for sequence in combinations(items, length):
print(sequence)
print("=" * 20 + "同一元素可以被使用多次" + "=" * 20)
for sequence in combinations_with_replacement(items, length):
print(sequence)
# ex6()
索引迭代
- 内置的enumerate
- 用法:list、 dict、 tuple、 set
- 使用start指定开始索引号,这种情况在遍历文件时想在错误消息中使用行号定位时候非常有用
def ex7():
lst = [1, 2, 3, 4]
start = 1
for index, val in enumerate(lst, start):
print("index:{}, val:{}".format(index, val))
# ex7()
多迭代
- 使用zip函数
- 可以使用dict(zip())打包生成字典
def ex8():
# 长度相同
x_val = [1, 2, 3, 4]
y_val = ['a', 'b', 'c', 'd']
# 长度不同时按最短结束迭代
x_val = [1, 2, 3]
y_val = ['a', 'b', 'c', 'd']
# 如果按长的进行终止迭代
# 使用zip_longest(x_val, y_val, fill_value="None")
for num, char in zip(x_val, y_val):
print(num, char)
# ex8()
链式迭代
from itertools import chain
def ex9():
x_val = [1, 2, 3, 4]
y_val = ['a', 'b', 'c', 'd']
for item in chain(x_val, y_val):
print(item)
# ex9()
参考书籍:python cookbook第三版