問題描述
我有以下字典包裝器:
class MyDict:
def __init__(self):
self.container = {}
def __setitem__(self, key, value):
self.container[key] = value
def __getitem__(self, key):
return self.container[key]
def __iter__(self):
return self
def next(self):
pass
dic = MyDict()
dic['a'] = 1
dic['b'] = 2
for key in dic:
print key
我的問題是我不知道如何實現 next
方法以使 MyDict
可迭代.任何意見,將不勝感激.
My problem is that I don't know how to implement the next
method to make MyDict
iterable. Any advice would be appreciated.
推薦答案
字典本身不是迭代器(只能迭代一次).您通常將它們設為 iterable,您可以為其生成多個 iterators 的對象.
Dictionaries are themselves not an iterator (which can only be iterated over once). You usually make them an iterable, an object for which you can produce multiple iterators instead.
完全刪除 next
方法,并讓 __iter__
在每次調用時返回一個可迭代對象.這可以像返回 self.container
的迭代器一樣簡單:
Drop the next
method altogether, and have __iter__
return an iterable object each time it is called. That can be as simple as just returning an iterator for self.container
:
def __iter__(self):
return iter(self.container)
如果你必須讓你的類成為一個迭代器,你必須以某種方式跟蹤當前的迭代位置并在到達結束"時提高 StopIteration
.一個簡單的實現可能是在第一次調用 __iter__
時將 iter(self.container)
對象存儲在 self
上:
If you must make your class an iterator, you'll have to somehow track a current iteration position and raise StopIteration
once you reach the 'end'. A naive implementation could be to store the iter(self.container)
object on self
the first time __iter__
is called:
def __iter__(self):
return self
def next(self):
if not hasattr(self, '_iter'):
self._iter = iter(self.container)
return next(self._iter)
此時 iter(self.container)
對象會為您跟蹤迭代位置,并在到達結束時引發 StopIteration
.如果底層字典被更改(添加或刪除鍵)并且迭代順序被破壞,它也會引發異常.
at which point the iter(self.container)
object takes care of tracking iteration position for you, and will raise StopIteration
when the end is reached. It'll also raise an exception if the underlying dictionary was altered (had keys added or deleted) and iteration order has been broken.
另一種方法是每次只存儲整數位置并索引到 list(self.container)
中,而忽略插入或刪除可以改變迭代順序的事實字典:
Another way to do this would be to just store in integer position and index into list(self.container)
each time, and simply ignore the fact that insertion or deletion can alter the iteration order of a dictionary:
_iter_index = 0
def __iter__(self):
return self
def next(self):
idx = self._iter_index
if idx is None or idx >= len(self.container):
# once we reach the end, all iteration is done, end of.
self._iter_index = None
raise StopIteration()
value = list(self.container)[idx]
self._iter_index = idx + 1
return value
在這兩種情況下,您的對象都是一個迭代器,只能迭代一次.一旦到達終點,就不能再重新開始了.
In both cases your object is then an iterator that can only be iterated over once. Once you reach the end, you can't restart it again.
這篇關于如何實現“下一步"?字典對象是可迭代的?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!