分享

Python迭代器

 网摘文苑 2023-02-12 发布于新疆

一、可迭代对象

1.迭代的概念

通过for循环遍历取值的过程叫做迭代。

2.可迭代对象

能够通过for循环遍历取值的对象叫做可迭代对象,比如字符串、列表、元组、字典、集合、range都属于可迭代对象。

可以通过isinstance函数来判断对象是否为可迭代对象:

from collections.abc import Iterableprint(isinstance([], Iterable)) # Trueprint(isinstance('', Iterable)) # Trueprint(isinstance({}, Iterable)) # Trueprint(isinstance((), Iterable)) # Trueprint(isinstance({'name': 'lucy'}, Iterable)) # True

二、迭代器

1.迭代器的概念

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

迭代器有两个基本的方法:iter() next(),字符串,列表或元组对象都可用于创建迭代器,迭代器对象可以使用常规 for 语句进行遍历,也可以使用 next() 函数来遍历。list、tuple等都是可迭代对象,可以通过iter()函数获取这些可迭代对象的迭代器。然后我们可以对获取到的迭代器不断使用next()函数来获取下一条数据。iter()函数实际上就是调用了可迭代对象的 __iter__ 方法。next()实际调用了 __next__()方法。

文章图片1

iter() ----- __iter__()

next() ----- __next__()

2.用iter()创建迭代器

将字符串转换为迭代器:

name = 'james'new_name = iter(name)print(type(name))  # <class 'str'>print(type(new_name))  # <class 'str_iterator'>print(isinstance(new_name, Iterator))  # True

将列表转换为迭代器:

list1 = [1, 2, 3, 4, 5]new_list1 = iter(list1)print(type(list1)) # <class 'list'>print(type(new_list1)) # <class 'list_iterator'>print(isinstance(new_list1, Iterator)) # True

3.遍历迭代器

通过for循环遍历

# 通过for循环遍历for i in new_name:    print(i)'''james'''

通过next()函数遍历

# 通过next()函数遍历, next()new_list1.__next__()print(next(new_list1)) # 1print(next(new_list1)) # 2print(next(new_list1)) # 3print(new_list1.__next__()) # 4print(new_list1.__next__()) # 5

next()函数获取,按照从前往后的顺序,每次只获取一个、每个值只能获取一次,当获取次数超过总长度时会报错StopIteration,可使用如下写法:

try:    print(new_list1.__next__())except StopIteration:    print('超过迭代器范围')

4.可迭代对象 VS 迭代器对象

先来打印一下可迭代对象和迭代器的属性列表

# 获取可迭代对象的属性列表list_2 = [1, 2, 3]print(dir(list_2))['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

通过打印结果中可以看出,可迭代对象方法列表中实现了__iter__方法,但并没有实现__next__方法;

# 获取迭代器对象的属性列表list_2 = [1, 2, 3]print(dir(iter(list_2)))['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__']

通过打印结果中可以看出,可迭代对象方法列表中既实现了__iter__方法,也实现了__next__方法;

所以,可以总结出迭代器(Iterator)与可迭代对象(Iterable)的区别:

  • 迭代器一定是可迭代对象,因为同时实现了__iter__方法和__next__方法,可以通过next()方法获取下一个值,但是每个值只能获取一次;
  • 但可迭代对象并不一定是迭代器,例如列表、字典、字符串,它们只实现了__iter__方法,如果想变成迭代器对象可以使用iter()进行转换;
  • 迭代器和可迭代对象都可以用作for循环遍历;
  • 只要可以用for循环遍历的都是可迭代对象,只要可以用next()函数遍历的都是迭代器对象;

5.使用迭代器的意义

使用for循环也可以遍历列表、字典等可迭代对象,列表、字典等可迭代对象是一次性将所有元素都加载到内存中,当可迭代对象的长度较长时,会占用系统资源,而使用迭代器,则是每次只获取一个,返回一个,不会造成资源浪费,在性能上大大优于未使用迭代器的场景

6.自定义一个迭代器

自定义一个迭代器,随机生成10个0-100的整数

class RandomIterator(object): def __init__(self): self.count = 0 # 只有使用__iter__方法才能使用for循环进行遍历,否则只能用next()获取迭代对象 # 使用了__iter__方法的都是可迭代对象 def __iter__(self): return self # 使用了__next__方法的都是迭代器对象 def __next__(self): if self.count == 10: raise StopIteration number = random.randint(0, 100) self.count += 1 return numberrandom_iter = RandomIterator()for i in random_iter: print(i)'''49359247291123573857'''

小结

  • 迭代器一定是可迭代对象,但可迭代对象不一定是迭代器;
  • 要想自己实现迭代器,必须实现__iter__方法和__next__方法。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多