On Tue, Feb 10, 2015 at 3:33 PM, Charles Hixson <charleshi...@earthlink.net> wrote: >> The proper version of the "hard way" is: >> >> 1) The __iter__ method of the iterable constructs a new iterator >> instance and returns it. >> >> 2) The __iter__ method of the *iterator* simply returns itself. >> >> 3) The __next__ method of the iterator tracks the current value and >> returns the next value. Note that the iterator should never store the >> iterable's data internally, unless the iterable is immutable and the >> calculation is trivial (e.g. a range object). Instead, it should >> determine the next value by referring to its source iterable. > > So if I'm understanding this correctly, I should implement as an internal > class within Grid something like: > class GridIter(Iterator):
Apart from the fact that you shouldn't have to explicitly subclass Iterator, yes. But this is the hard way to do things. The easy way is to simply define an __iter__ method on your Grid which returns an iterator - and one excellent form of iterator, for custom classes like this, is a generator object. Your original code can slot happily in, with one tiny change: class Grid: blah blah def __iter__(self): for row in range(self._rows): for col in range(self._cols): if self._grid[row][col]: yield self._grid[row][col] The only change is to remove the explicit StopIteration at the end; once your generator function terminates, the generator object will raise StopIteration forever afterward, without any help from you. (Also, post-PEP479, the explicit raise will actually cause RuntimeError, so it's not just superfluous, but actually a problem.) But I'm guessing that your grid and rows are actually iterable themselves. If they are, you can cut the code down to this: def __iter__(self): for row in self._grid: for cell in row: if cell: yield cell or a generator expression: def __iter__(self): return (cell for row in self._grid for cell in row if cell) or itertools.chain and filter, if you so desired. As long as you return an iterator, you're fine. This is far and away the easiest way to make a class iterable. ChrisA -- https://mail.python.org/mailman/listinfo/python-list