python中的迭代器和可迭代对象

1.可迭代对象

迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。

通俗的来讲,通过for循环对list,tuple,dict,str,set等数据类型进行遍历的过程,就叫做迭代

我们把可以通过for...in...这类语句迭代读取一条数据供我们使用的对象称之为可迭代对象(Iterable)

2.如何判断一个对象是否可以迭代

可以使用 isinstance() 判断一个对象是否是 Iterable 对象:

# 元组,列表,字典,字符串,集合,range都是可迭代对象
from collections import Iterable

# 判断对象是否是指定类型
result = isinstance((3, 5), Iterable)
print("元组是否是可迭代对象:", result)

result = isinstance([3, 5], Iterable)
print("列表是否是可迭代对象:", result)

result = isinstance({"name": "张三"}, Iterable)
print("字典是否是可迭代对象:", result)

result = isinstance("hello", Iterable)
print("字符串是否是可迭代对象:", result)

result = isinstance({3, 5}, Iterable)
print("集合是否是可迭代对象:", result)

result = isinstance(range(5), Iterable)
print("range是否是可迭代对象:", result)

result = isinstance(5, Iterable)
print("整数是否是可迭代对象:", result)

# 提示: 以后还根据对象判断是否是其它类型,比如以后可以判断函数里面的参数是否是自己想要的类型
# 1.判断整数
result = isinstance(5, int)
print("整数是否是int类型对象:", result)

# 2.判断类
class Student(object):
    pass

stu = Student()
result = isinstance(stu, Iterable)
print("stu是否是可迭代对象:", result)

result = isinstance(stu, Student)
print("stu是否是Student类型的对象:", result)


可迭代对象的本质:遍历可迭代对象的时候其实获取的是可迭代对象的迭代器, 然后通过迭代器获取对象中的数据

自定义可迭代对象:在类里面定义__iter__方法创建的对象就是可迭代对象

使用迭代器和可迭代对象时,要导入Iterable和Iterator模块

from collections import Iterable
from collections import Iterator

# 自定义可迭代对象: 在类里面定义__iter__方法创建的对象就是可迭代对象
class MyList(object):

    def __init__(self):
        self.my_list = list()

    # 添加指定元素
    def append_item(self, item):
        self.my_list.append(item)

    def __iter__(self):
        # 可迭代对象的本质:遍历可迭代对象的时候其实获取的是可迭代对象的迭代器, 然后通过迭代器获取对象中的数据
        my_iterator = MyIterator(self.my_list)
        return my_iterator

# 自定义迭代器对象: 在类里面定义__iter__和__next__方法创建的对象就是迭代器对象
# 迭代器是记录当前数据的位置以便获取下一个位置的值
class MyIterator(object):

    def __init__(self, my_list):
        self.my_list = my_list
        # 记录当前获取数据的下标
        self.current_index = 0
        # 判断当前对象是否是迭代器
        result = isinstance(self, Iterator)
        print("MyIterator创建的对象是否是迭代器:", result)

    def __iter__(self):
        return self

    # 获取迭代器中下一个值
    def __next__(self):
        if self.current_index < len(self.my_list):
            self.current_index += 1
            return self.my_list[self.current_index - 1]
        else:
            # 数据取完了,需要抛出一个停止迭代的异常
            raise StopIteration

my_list = MyList()
my_list.append_item(1)
my_list.append_item(2)
result = isinstance(my_list, Iterable)
print(result)
for value in my_list:
    print(value)


注意,当我们已经迭代完最后一个数据之后,再次调用next()函数会抛出StopIteration的异常,来告诉我们所有数据都已迭代完成,不用再执行next()函数了。

3.迭代器

迭代器:在类里面定义__iter__和__next__方法创建的对象就是迭代器,迭代器的作用就是记录当前数据的位置,以便获取下一个值

from collections import Iterable
from collections import Iterator


class MyList(object):

    def __init__(self):
        self.my_list = list()

    # 添加指定元素
    def append_item(self, item):
        self.my_list.append(item)

    def __iter__(self):
        # 可迭代器对象的本质:遍历可迭代对象的时候其实获取的是可迭代对象的迭代器,然后通过迭代器获取对象中的数据
        my_iterator = MyIterator(self.my_list)
        return my_iterator

# 自定义迭代器对象:在类里面定义__iter__和__next__方法创建的对象就是迭代器对象
# 迭代器是记录当前数据的位置,以便获取下一个位置的值
class MyIterator(object):

    def __init__(self, my_list):
        self.my_list = my_list

        # 记录当前获取数据的下标
        self.current_index = 0

    def __iter__(self):
        return self

    # 获取迭代器中下一个值
    def __next__(self):
        if self.current_index < len(self.my_list):
            self.current_index += 1
            return self.my_list[self.current_index - 1]
        else:
            # 数据取完了,需要抛出一个停止迭代的异常
            raise StopIteration


class MyItertor(object):
    # 获取迭代器中下一个值
    def __next__(self):
        if self.current_index < len(self.my_list):
            self.current_index += 1
            return self.my_list[self.current_index - 1]
        else:
            # 数据取完了,需要抛出一个停止迭代的异常
            raise StopIteration

# 创建一个自定义的可迭代对象
my_list = MyList()
my_list.append_item(1)
my_list.append_item(2)

# 获取可迭代对象的迭代器
my_iterator = iter(my_list)
print(my_iterator)
# 获取迭代器中下一个值
# value = next(my_iterator)
# print(value)

# 方法一:使用try捕获异常
# while True:
#     try:
#         value = next(my_iterator)
#         print(value)
#     except StopIteration as e:
#         break

# 方法二:使用for,内部已经捕获
# for value in my_list:
#     print(value)

# 测试:通过迭代器获取对应的数据
for value in my_iterator:
    print(value)

总结:
 for...in循环本质: 如果遍历的对象是可迭代对象,那么需要通过iter函数获取迭代器,然后通过next函数获取迭代器中下一个值 for内部捕获了停止迭代的异常,while循环没有捕获,需要自己捕获

4.迭代器的应用场景

数学中有个著名的斐波拉契数列(Fibonacci),数列中第一个数为0,第二个数为1,其后的每一个数都可由前两个数相加得到:

                        0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...

现在我们想要通过for...in...循环来遍历迭代斐波那契数列中的前n个数。那么这个斐波那契数列我们就可以用迭代器来实现,每次迭代都通过数学计算来生成下一个数。

class Fibonacci(object):

    def __init__(self, num):
        # num:表示生成多少个fibonacci数字
        self.num = num
        # 记录fibonacci前两个值
        self.a = 0
        self.b = 1
        # 记录当前生成数字的索引
        self.current_index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.current_index < self.num:
            result = self.a
            self.a, self.b = self.b, self.a + self.b
            self.current_index += 1
            return result
        else:
            raise StopIteration
fib = Fibonacci(5)
# 循环打印所有的fibonacci数字
for value in fib:
    print(value)









猜你喜欢

转载自blog.csdn.net/anyiVIP/article/details/79805383
今日推荐