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?