迭代是访问集合元素的一种方式。 迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。 迭代器只能往前不会后退。

1.可迭代对象 字符串 列表 字典 元祖 集合 range()
我们已经知道可以对list、tuple、str等类型的数据使用for…in…的循环语法从其中依次拿到数据进行使用,我们把这样的过程称为遍历,也叫迭代。

但是,是否所有的数据类型都可以放到for…in…的语句中,然后让for…in…每次从中取出一条数据供我们使用,即供我们迭代吗?

# for i in "laowang":
#     print(i,end=' ')
# print()
# for i in [1,2,3,4,5]:
#     print(i,end=' ')
# print()
# for i in range(1,11):
#     print(i,end=' ')
# print()

可迭代对象包括:

列表、字典、集合、字符串等数据类型。

数字类型不可迭代

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

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

在python3.5 3.7.2之前不需要再abc里引入

from collections.abc import Iterable # 可迭代对象

# isinstance(要判断的对象,数据类型)
print(isinstance([1, 2, 3], Iterable))
print(isinstance((1, 2, 3), Iterable))
print(isinstance(range(1, 11), Iterable))
print(isinstance(345, Iterable))

可迭代对象的本质

我们分析对可迭代对象进行迭代使用的过程,发现每迭代一次(即在for…in…中每循环一次)都会返回对象中的下一条数据,一直向后读取数据直到迭代了所有数据后结束。

那么,在这个过程中就应该有一个“人”去记录每次访问到了第几条数据,以便每次迭代都可以返回下一条数据。
我们把这个能帮助我们进行数据迭代的“人”称为迭代器(Iterator)。

可迭代对象的本质就是可以向我们提供一个这样的中间“人”即迭代器帮助我们对其进行迭代遍历使用。

可迭代对象通过__iter__方法向我们提供一个迭代器,我们在迭代一个可迭代对象的时候,实际上就是先获取该对象提供的一个迭代器,然后通过这个迭代器来依次获取对象中的每一个数据.

那么也就是说,一个具备了__iter__方法的对象,就是一个可迭代对象。


# class My_list(object):
#     def __init__(self):
#         self.aa = []
#
#     def add(self,item):
#         self.aa.append(item)
#
#     def __iter__(self):
#         pass
#
# mm = My_list()
# mm.add(1)
# mm.add(2)
# mm.add(3)
# mm.add(4)
# mm.add(5)
#
# from collections.abc import Iterable
# print(isinstance(mm,Iterable))
#
# for i in mm.aa:
#     print(i)

iter()和next()

a_list = [11, 22, 33, 44, 55]
# iter() 获取可迭代对象的迭代器
ali_list = iter(a_list)

# next()  获取迭代器的下一条数据
# print(next(ali_list))
# print(next(ali_list))
# print(next(ali_list))
# print(next(ali_list))
# print(next(ali_list))
# print(next(ali_list))           #StopIteration 停止迭代异常

from collections.abc import Iterable  # 迭代器

print(isinstance(ali_list, Iterable))
print(isinstance(a_list, Iterable))  # 只是可迭代对象

iterator()

一个实现了iter方法和next方法的对象,就是迭代器。

# class MyIterator():
#     """迭代器类"""
#     def __init__(self,alist):
#         """属性初始化和赋值"""
#         self.alist = alist
#         self.weizhi = 0        #记录遍历位置
#
#     def __iter__(self):
#         """获取迭代器,自身就为迭代器,所以返回自身"""
#         return self
#
#     def __next__(self):
#         """获取迭代器下一位置数据"""
#         if self.weizhi < len(self.alist):
#             item = self.alist[self.weizhi]
#             self.weizhi += 1
#             return item
#         else:
#             raise StopIteration     #主动抛出 停止异常迭代
#
#
#
# if __name__ == '__main__':
#     a_list = [1, 2, 3, 4, 5, 6]
#     ml = MyIterator(a_list)
#     # for i in ml:
#     #     print(i)
#
#
#     # for循环本质
# if __name__ == '__main__':
#     a_list = [1, 2, 3, 4, 5, 6]
#     while True:
#         try:
#             ret = next(ml)
#             print(ret)
#         except StopIteration as e:
#             print(e)
#             break


# from timeit import time
# def outer(fun):
#     def inner():
#         a = time.time()
#         fun()
#         b = time.time()
#         print(b - a)
#     return inner
#
#
# @outer
# def fun():
#     print("hello")
#     time.sleep(1)
#     print("python")
# fun()

使用迭代器构造斐波那契数列

# 单词  current-位置

# class Fei():
#     """斐波那锲数列类"""
#     def __init__(self,nu):
#         """实例属性的初始化和赋值"""
#         self.nn = nu
#         self.current = 0         #记录位置
#         self.sum1 = 0           #定义初始值
#         self.sum2 = 1
#     def __iter__(self):
#         """获取迭代器,即自身"""
#         return self
#     def __next__(self):
#         """获取迭代器下一位置数据"""
#         if self.current < self.nn:
#             num = self.sum1
#             self.sum1,self.sum2 = self.sum2,self.sum1 + self.sum2
#             self.current += 1
#             return num
#         else:
#             raise StopIteration
# if __name__ == '__main__':
#     fei = Fei(int(input('请输入:')))
#     """判断是否为迭代器"""
# from collections.abc import Iterator,Iterable
# print(isinstance(fei,Iterable))


# for i in fei:
#     print(i)

# print(list(fei))          #迭代器对象只能被查看一次
# print(tuple(fei))

# while True:
#     try:
#         print(next(fei))
#     except StopIteration as e:
#         break


class Fei:
    def __init__(self, nn):
        self.nn = nn
        self.a, self.b = 0, 1
        self.weizhi = 0
        self.list1 = []

    def __iter__(self):
        return self

    def __next__(self):
        sum = self.a
        if self.weizhi < self.nn:
            self.a, self.b = self.b, self.a + self.b
            self.weizhi += 1
            return sum
        else:
            raise StopIteration
    # def sb(self):
    #     self.list1.append(sum)
    #     self.list1.reverse()
    #     print(self.list1)


if __name__ == '__main__':
    aa = Fei(10)
    # print(aa)

    # print(list(aa[::-1]))

a = Fei(10)
l = sorted(a, reverse=True)
print(list(l))