Iteration and iterators in python

Iteration is often seen in python and even programming. The so-called iteration is a way to access elements of a collection. We call the process of taking iterative objects in sequence, called traversal, also called iteration, and common in python can be The iterable objects include tuples, lists, dictionaries, sets, ranges, and strings. How to know whether our objects are iterable through code? We import the Iterable class of the collections module and return the boolean through the isinstance() method. The value True/False to determine whether it is iterable:

from collections import Iterable
 # Lists, tuples, dictionaries, strings, sets, ranges and other objects are iterable objects
 # Determine whether the object is an iterable object
 result = isinstance ([ 3 , 5 ] , Iterable)
 print ( "Whether the list is an iterable object is an iterable object: " , result)


result = isinstance (( 3 , 5 ) , Iterable)
 print ( "Is the tuple iterable:" , result)

result = isinstance ({ "name" : "Chen Xiao" , "age" : 20 } , Iterable)
 print ( "Is the dictionary iterable:" , result)

result = isinstance ({ 3 , 5 } , Iterable)
 print ( "Is the collection iterable:" , result)

result = isinstance ( "apple" , Iterable)
 print ( "Is the string iterable:" , result)

result = isinstance ( range ( 5 ) , Iterable)
 print ( "Is range iterable:" , result)

# for i in 5:
 # print(i)

 result = isinstance ( 5 , Iterable)
 print ( "Is the int object iterable:" , result)

# Hint: You can judge whether the object is of the specified type
 result = isinstance ( 5 , int )
 print ( "Whether the int object is of type:" , result)


# Extension - the type of the parameter can be judged according to isinstance
 def show (name , age):
     if not isinstance (age , int ):
         print ( "age is not of type int" )

    print(name, age)


show("陈晓", "20")

class Student ( object ):
     pass
 stu = Student()
 # Determine whether the object is of the specified type
 result = isinstance (stu , Student)
 print (result)




# int, default custom objects are not iterable, not iterable objects

 
 

The following results can be easily obtained:

whether the list is an iterable: True
Whether the tuple is an iterable object: True
Whether the dictionary is an iterable object: True
whether the collection is an iterable: True
Whether the string is an iterable object: True
range是否是可迭代对象: True
int对象是否是可迭代对象: False
int对象是否是类型: True
age不是int类型
鹿晗 20
True
那么可迭代对象的本质是什么呢?

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

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

下面我们写一个自定义的可迭代对象:

# 自定义可迭代对象: 在类里面提供一个__iter__方法创建的对象就是可迭代对象
from collections import Iterable


class StudentList(object):

    def __init__(self):
        super(StudentList, self).__init__()
        self.my_list = list()


    # 添加信息
    def append_item(self, item):
        # 添加数据到系统的列表
        self.my_list.append(item)

    # 可迭代对象方法
    def __iter__(self):
        # 可迭代对象之所能够迭代数据是通过迭代器完成的-> 可迭代对象的本质就是通过迭代器把数据依次迭代出来的
        pass


student_list = StudentList()
student_list.append_item("苹果")
student_list.append_item("西瓜")
result = isinstance(student_list, Iterable)
print(result)

# for value in student_list:
#     print(value)

上面的代码重点放在__iter__()方法上面,而且这个方法里面我没有写任何代码,pass只是表示代码不报错。执行结果为:True

但是这个对象虽然是判断为可迭代,但是他不能通过我们的for循环取遍历,因为他不具有迭代器。如果放开我注释里的最后两行代码,就会报错

那什么是迭代器呢?

一个实现了__iter__方法和__next__方法的对象,就是迭代器,所以,我们要想构造一个迭代器,就要实现它的__next__方法。但这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现__iter__方法,而__iter__方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的__iter__方法返回自身即可。

通过下面我们创建自定义的迭代器对象:

# 自定义迭代器对象: 在类里面提供__iter__和__next__方法创建的对象就是迭代器

# 自定义可迭代对象: 在类里面提供一个__iter__方法创建的对象就是可迭代对象
from collections import Iterable
from collections import Iterator


clas StudentList(object):

    def __init__(self):
        super(StudentList, self).__init__()
        self.my_list = list()


    # 添加信息
    def append_item(self, item):
        # 添加数据到系统的列表
        self.my_list.append(item)

    # 可迭代对象方法
    def __iter__(self):
        # 可迭代对象之所能够迭代数据是通过迭代器完成的-> 可迭代对象的本质就是通过迭代器把数据依次迭代出来的
        student_iterator = StudentIterator(self.my_list)
        result = isinstance(student_iterator, Iterator)
        print("student_iterator:", result)
        return student_iterator


# 自定义迭代器
class StudentIterator(object):

    def __init__(self, my_list):
        super(StudentIterator, self).__init__()
        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):
            value = self.my_list[self.current_index]
            # 取值完成以后需要对下标加上1
            self.current_index += 1
            return value
        else:
            # 超出范围抛出停止迭代的异常
            raise StopIteration

# 创建可迭代对象
student_list = StudentList()
student_list.append_item("苹果")
student_list.append_item("西瓜")
result = isinstance(student_list, Iterable)
print(result)

for value in student_list:
    print(value)
 
 

执行结果:

True
student_iterator: True
苹果
西瓜

代码分析:

首先我们导入必要的模块,紧接着我们创建了一个StudentList的新式类,类里写了三个方法,第一个方法是初始化__init__方法,我们让他复写了父类的__init__,再给他带了一个空列表作为他的my_list属性,然后添加了append_item()方法用来往my_list添加内容,最后定义__iter__方法,在__iter__方法里调用了接下来我们准备好的自定义迭代器类实例化的对象,并且用return返回,而这个对象刚好是我们需要的迭代器,在StudentIterator这个类里面,我们还是初始化了父类init,并把my_list给传过来作为自己的属性,并且增加了一个记录当前元素下表的current-index,从0开始计数。。。算了不说了一切竟在代码中。。。


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325660088&siteId=291194637