Python Forum

Full Version: iterator from an iterator
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
in a function i have an iterator. i'd like to create a new iterator that wraps around that first iterator and modifies each data item. is there a way to do this without coding a generator? an example use case starts with a iterator that yields bytes items. i want to make (and return) an iterator that yields the same data transparently converted to str items.
You can write your own class to decorate behavior of an iterator, e.g.

x = [1,2,3]
class IterDecor:
    def __iter__(self):
        return self

    def __next__(self):
        value = next(self._iterator)
        return str(value * value)
    
    def __call__(self, iterator):
        self._iterator = iterator
        return self

c = IterDecor()
x = c(iter(x))  # decorate behavior of the default iterator `iter(x)`

for z in x:
    print(z, type(z))
Output:
1 <class 'str'> 4 <class 'str'> 9 <class 'str'>
You can also use a generator expression
>>> seq = [b'a', b'a', b'c']
>>> seq2 = (x.decode() for x in seq)
>>> for x in seq2:
...     print(x)
... 
a
a
c
An alternative is to use map()
>>> seq = [b'a', b'a', b'c']
>>> seq2 = map(bytes.decode, seq)
>>> for x in seq2:
...     print(x)
... 
a
a
c
this is a function that needs to return the modified iterator. should it just return the expression?