python - How to implement "next" for a dictionary object to be iterable? -


i've got following wrapper dictionary:

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  key in dic:     print key 

my problem don't know how implement next method make mydict iterable. advice appreciated.

dictionaries not iterator (which can iterated on once). make them iterable, object can produce multiple iterators instead.

drop next method altogether, , have __iter__ return iterable object each time called. can simple returning iterator self.container:

def __iter__(self):     return iter(self.container) 

if must make class iterator, you'll have somehow track current iteration position , raise stopiteration once reach 'end'. naive implementation store iter(self.container) object on self first time __iter__ called:

def __iter__(self):     return self  def next(self):     if not hasattr(self, '_iter'):         self._iter = iter(self.container)     return next(self._iter) 

at point iter(self.container) object takes care of tracking iteration position you, , raise stopiteration when end reached. it'll raise exception if underlying dictionary altered (had keys added or deleted) , iteration order has been broken.

another way store in integer position , index list(self.container) each time, , ignore fact insertion or deletion can alter iteration order of dictionary:

_iter_index = 0  def __iter__(self):     return self  def next(self):     idx = self._iter_index     if idx none or idx >= len(self.container):         # once reach end, iteration done, end of.         self._iter_index = none         raise stopiteration()     value = list(self.container)[idx]     self._iter_index = idx + 1     return value 

in both cases object iterator can iterated on once. once reach end, can't restart again.


Comments