【问题标题】:call dict iterator function for each member in dict为dict中的每个成员调用dict迭代器函数
【发布时间】:2017-07-17 20:44:51
【问题描述】:

我想为字典/列表中的每个项目执行一些功能。我试过这样做,但它没有给出预期的结果。这是代码。

class GroupDict(dict):
def iteritems(self):
    # do some operation for every member in dict
    print "in __iter__"
    return super(GroupDict, self).iteritems()
a = GroupDict()
a['a'] = 0
a['b'] = 1
for key in a.iteritems():
    print key

为此我得到了输出

in __iter__ ('a', 0) ('b', 1)

但预期是

in __iter__ ('a', 0) in __iter__ ('b', 1)

我不想在 for 循环中进行操作,但我在课堂上提到的任何内容都应该为每个成员执行。请帮我解决这个问题。

【问题讨论】:

  • 为什么你要继承表单 dict 并覆盖 iteritems 来实现这一点?只需for k,v in a.iteritems(): f(k, v) 即可获得您想要的任何功能f。在for循环中做操作有什么问题?
  • 我不能在 for 循环中添加这段代码,部分原因是代码的结构方式,其次,如果走这条路,我必须更改很多东西。

标签: python-2.7 dictionary iterator


【解决方案1】:

iteritems() 在循环实际开始之前只被调用一次。

让我们看看为什么。这个循环:

for x in EXP:
    do_something()

大致翻译为:

it = iter(EXP)
while True:
    try:
        x = next(it)
    except StopIteration:
        break
    do_something()

如果你想为每个成员做点什么,通过yielding from iteritems() 做你想做的事情会更容易:

def iteritems(self):
    for k, v in super(GroupDict, self).iteritems():
        print "doing something with %s / %s" % (k,v)
        yield k, v

【讨论】:

  • 也尝试过包装 iter 方法,但这也只调用一次。那么你所说的dict-iterator是指哪种方法?
  • @ShriShinde 是的,你需要覆盖 next(在 Python 2 中,__next__ 在 Python 3 中)。
  • @ShriShinde 你需要定义你自己的迭代器类,并在它的__next__() 方法(python2 中的next())中做任何你想做的事,并覆盖iteritems()返回您自己的迭代器。一个更简单的选择是使用yield 使iteritems() 成为生成器。我会把它添加到我的答案中
  • @shx2 是的,用生成器覆盖 iteritems 可能是最简单的方法。
猜你喜欢
  • 2021-06-13
  • 1970-01-01
  • 2015-02-28
  • 2020-09-07
  • 1970-01-01
  • 2013-08-10
  • 2017-10-05
  • 1970-01-01
  • 2020-03-10
相关资源
最近更新 更多