Logo

郎哥编程

使用Python的迭代器遍历可迭代对象

2018-11-29 862

迭代器也是用来遍历对象成员的,前面讨论过使用for循环遍历序列对象成员,为什么Python还要提供迭代器呢?


1、为什么要使用迭代器?


使用for循环可以遍历序列对象,列表、元组、字符串都是序列对象,序列对象都有索引,通过索引可以访问序列对象的成员。在用for循环遍历序列对象时,即可以使用序列对象的索引来遍历,也可以使用序列项来遍历,for循环使用序列项遍历对象时,就用到了迭代器。另外,Python也有不是序列对象的数据,例如集合、字典、文件等,如何遍历这些数据类型的成员呢,这也需要用到迭代器。

Python提供的迭代器是非常强大的,它不仅可以遍历序列对象,也可以遍历非序列对象,例如遍历字典的所有键,集合的所有成员等等。迭代器本身提供了一个next方法,用于获取下一个对象成员,当用next方法获取全部成员后,再次调用next方法时,会引发StopIteration异常,这个异常不是错误,只是表示迭代已完成,因此使用迭代器迭代对象成员时,需要加入异常处理语句。


2、 哪些是可迭代对象?


迭代器提供了统一的访问接口,只要实现了__iter__和__next__方法的对象,都属于可迭代对象,可以使用迭代器进行迭代访问。序列对象包括列表、元组和字符串;非序列对象包括字典、集合和文件;实现了__iter__和__next__方法的自定义对象也属于可迭代对象。

例如:

class test():
    def __init__(self,data=1):
        self.data = data
    def __iter__(self):
        return self
    def __next__(self):
        if self.data > 5:
            raise StopIteration
        else:
            self.data+=1
            return self.data
 
for item in test(3):
    print(item);

上面的代码定义了一个test类(关于Python类的知识,在后面的章节会有详细介绍),test类实现了__iter__和__next__方法,属于可迭代对象。for……in……循环语句实现对test类对象的迭代访问,首先它通过__iter__方法获得test类的迭代器,然后循环调用__next__方法获得test对象,直至test类的data属性大于5时停止迭代。


3、如何使用迭代器?


Python提供的iter()函数可以从可迭代对象中获得该对象的迭代器,然后使用迭代器的next方法获取对象。因为迭代器在迭代完所有对象成员后,会引发StopIteration异常,因此需要把迭代代码放入到try-except块中(异常处理语句,在后面的章节会有详细介绍)。

例1:查找一个词是否在给出的词组中。

词组是多个词的组合,在词组中查找一个词,查找的词为查询词。最好的处理方法就是遍历整个词组,依次与查询词进行匹配,匹配成功说明查询词出现在词组中。程序流程图如下:

image.png                                        

图1  词查询流程图

程序一开始先用列表初始化词组,然后要求用户输入查询词,再使用迭代器迭代词组列表,在词组列表的迭代过程中,获取每个词对象,并与查询词进行匹配。若匹配成功,输出匹配成功信息并执行break语句跳出迭代,程序结束;若匹配失败则进入下一轮迭代。当迭代全部结束后,说明词组中没有与查询词相匹配的词,输出匹配失败信息,程序结束。下面给出例1的程序代码。

#初始化词组
wordList = ['Java','Python','PHP','C++','Basic','Fortran'];
#要求用户输入查询词
queryWord = input("请输入查询词:");
#迭代wordList
#获得迭代器
iterword = iter(wordList);
while True:
    try:
        tempword = next(iterword);
        if tempword == queryWord:
            print("%s匹配成功" % queryWord);
            break;
    except StopIteration:
        print("%s匹配失败" % queryWord);
        break;

在Python语言,判断两字符串是否相等,可以使用“==”比较运算符进行判断,也可以使用“in”成员运算符进行判断,这两种运算符都返回布尔值,可以用在if表达式中。“==”比较运算符主要用于判断两个字符串的内容是否相等;“in”成员运算符主要用于判断两个字符串的内存地址是否相等。

try-except是Python的异常处理语句,当需要Python捕获异常代码时,需要把认为可能会出现异常的代码包括在try语句块中,在程序执行时,如果try内语句发生错误就会抛出异常,except语句会捕获异常,except语句块内的代码将会被执行,这样就可以处理异常错误了。因为迭代器在迭代完所有对象成员后,会引发StopIteration异常,因此需要把迭代代码放入到try-except块中。

上面代码的功能也可以使用for循环实现,使用for循环对词组进行迭代,操作上更为简单方便。

#初始化词组
wordList = ['Java','Python','PHP','C++','Basic','Fortran'];
#要求用户输入查询词
queryWord = input("请输入查询词:");
#迭代wordList
bFind = False;
for tempword in wordList:
    if tempword == queryWord:
        print("%s匹配成功" % queryWord);
        bFind = True;
        break;
if bFind == False:
    print("%s匹配失败" % queryWord);

    在for……in……循环中,序列对象列表会自动产生迭代器,并自动调用迭代器的next方法,因此不需要处理try-except语句。

例2:用字典实现图书信息表,并能通过图书的ISBN号查询到图书信息。

每本图书都有唯一的ISBN号,可以把图书的ISBN号作为图书信息表的唯一标识。题目要求用字典来实现,字典分为key和value两部分,key为键,value为键的属性,key和value是一一对应的关系。图书的ISBN可以作为字典的key,图书的其它信息可以作为字典的value,图书的其它信息包括图书名称、作者、出版社、价格,字典的value可以用Python列表来实现。程序流程图如下:

image.png


图 2  图书信息查询流程图

程序一开始先初始化图书信息字典,字典的key为图书的ISBN号,字典的value为图书的名称、作者、出版社、价格信息,value为Python列表对象。然后要求用户输入图书的ISBN号,再使用迭代器遍历字典的key,在遍历字典key的过程中,如果输入的ISBN与key匹配,则输出图书信息并执行break语句跳出迭代,程序结束。当迭代全部完成后,输出匹配失败信息,程序结束。下面给出例2的程序代码。

#初始化图书字典
from pip._vendor.six import iterkeys
bookDic = {'9787115461476':['深度学习','伊恩·古德费洛','人民邮电出版社','126.00元'],
           '9787111511632':['计算机科学导论','佛罗赞','机械工业出版社','53.60元'],
           '9787302490487':['机器人仿真与编程技术','杨辰光 ','清华大学出版社','109.00元']};
#要求用户输入查询词
isbn = input("请输入ISBN号:");
#迭代bookDic
#获得迭代器
iterkeys = iter(bookDic);
while True:
    try:
        tempkey = next(iterkeys);
        if tempkey == isbn:
            print(bookDic[tempkey]);
            break;
    except StopIteration:
        print("%s匹配失败" % isbn);
        break;

使用Python提供的iter函数获取字典key的迭代器,在字典key的迭代过程中,next函数返回key的值。bookDic使用“[]”访问运算符可以把key作为索引获取字典的value。


代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论