使用 iter 函数的字典迭代

Dictionary iteration with iter func

我正在尝试使用这个迭代我的字典:

it = iter(db)
for i in it:
    print(i)

但是当我运行它时发生的是一个无限循环打印整个字典而不是在字典的键上

我用这个作为输入:

ppl = Course(123, 'Principles of Programming Languages') 
os = Course(133, 'Operating Systems') 
db = DB()
db.setCourse(ppl, 'SE', 2, 1)
db.setCourse(os, 'SE', 3, 1) 

我的输出是:

{123: ('Principles of Programming Languages', 'SE', 2, 1), 133: ('Operating Systems', 'SE', 3, 1)}
{123: ('Principles of Programming Languages', 'SE', 2, 1), 133: ('Operating Systems', 'SE', 3, 1)}
{123: ('Principles of Programming Languages', 'SE', 2, 1), 133: ('Operating Systems', 'SE', 3, 1)}

在一个永无止境的循环中。 我很确定我的 next 搞砸了。

编辑 数据库代码很长,这是它的 iter 部分:

class DB()
    DataBase = {} 
    def __iter__(self):
        return iter(self.DataBase)
    def getCourse(self,cnum):
        for i in self.DataBase:
            if i == cnum:
                return self.DataBase[i]
    def getCoursesByDept(self,dept):
        for key, value in self.DataBase.items(): 
            if dept in value: 
                return self.DataBase[key]
    def getCoursesByDeptYear(self,dept,year):
        for key, value in self.DataBase.items():
            if dept in value and year in value:
                return self.DataBase[key]
    def getCoursesByDeptYearSem(self,dept,year,semester):
        for key, value in self.DataBase.items():
            if dept in value and year in value and semester in value:
                return self.DataBase[key]
    def setCourse(self,Course,dept,year,semester):
        self.DataBase[Course.cnum] = (Course.name,dept,year,semester)
    def removeCourse(self,cnum):
        for i in self.DataBase.keys():
            if i == cnum:
                del self.DataBase[i]

正确的输出是:

Course 123: Principles of Programming Languages 
Course 133: Operating Systems 

看起来最简单的修复是:

class DB():
    ...
    def __iter__(self):
        return iter(self.DataBase)

并取出__next__方法

要创建自己的密钥,您需要自己遍历 __iter__:

中的密钥
    def __iter__(self):
        for key in self.Database:
            yield key

它创建了一个生成器,你仍然不需要 __next__;如果你有一个__next__,那么你需要收集钥匙,然后return一个接一个。

一旦你拥有 return 每个键,你需要 raise StopIteration 每次再次调用 __next__ -- 这意味着你只能迭代一次 -- 最好坚持使用一个以上两个选项。

您当前遇到无限循环的原因是每次 __next__ 都称呼您 return 整个字典 -- 不检查您是否完成。

有关创建迭代器的更详尽的解释,请参阅 this answer


如果您希望 DB class 看起来与 dict 相同,请添加 keys()items()values();如果您不关心或不需要这些,则可以选择上面的第二个选项,或者创建您自己的选项。第二个选项可能如下所示:

    def __iter__(self):
        for key, value in self.Database.items():
            yield key, value

这里发生的是,对于 DB 中的每个 keyvalue 对,在迭代时两者都是 return。所以你原来的循环应该是这样的:

it = iter(db)
for k, v in it:
    print('%s: %s' % (k, v))