less awkward is: some_iter = map(lambda x: x if print(x) else x, some_iter)
The tuple has a ~50% overhead, the case statement ~15%, compared to the generator. I think that the less awkward syntax solves the problem fine (if you can come up with it). I like that it's explicit rather than requiring someone to know what itertools.tap does. On Sun, Oct 25, 2020 at 4:27 PM Samuel Freilich via Python-ideas < python-ideas@python.org> wrote: > This seems like it might be a reasonable thing to have in intertools? It's > not hard to write this sort of thing with map: > > some_iter = map(lambda x: (print(x), x)[1], some_iter) > > But it's a little awkward. (Though maybe I'm missing a less awkward way to > do that.) > > Java has Stream.peek for similar functionality, while Stream.forEach is > analogous to Python's map. > > On Sun, Oct 25, 2020 at 9:02 AM <anderssonpub...@gmail.com> wrote: > >> Python has many tools for iteration, such as map and filter, that change >> an iterator into another iterator without consuming the iterator. These >> make it simple to deal with many items in a list without consuming >> excessive memory. >> >> Occasionally it is useful to be able to tap into iterator items and >> execute a function (such as a side effect to validate elements or print >> them) without making any changes to the overall iterator. This is similar >> to the idea of a tap in rxjs: >> https://rxjs-dev.firebaseapp.com/api/operators/tap. >> >> The proposed interface would be: >> def generate_items() -> list[int]: >> some_iter = range(10) >> some_iter = tap(assert_int, some_iter) >> some_iter = tap(print, some_iter) >> return list(some_iter) >> >> This would be useful to (for example): >> 1. Debug chained iterators without a debugger (at the moment you would >> have to convert the list and then print the whole list or include a print >> statement in one of the chained functions) >> 2. Check that items in an iterator conform to assumptions and raising >> exceptions if they do not >> 3. Improve type hints in editors since after the assert is executed all >> items conform to the assert in the tap (for example, they are an integer) >> >> The implementation would be quite simple (at least in python): >> def tap(func: typing.Callable[[T], typing.Any], iter: typing.Iterable[T]) >> -> typing.iterable[T]: >> for item in iter: >> func(item) >> yield item >> >> Thoughts? >> _______________________________________________ >> Python-ideas mailing list -- python-ideas@python.org >> To unsubscribe send an email to python-ideas-le...@python.org >> https://mail.python.org/mailman3/lists/python-ideas.python.org/ >> Message archived at >> https://mail.python.org/archives/list/python-ideas@python.org/message/7Q3NR4SKUC72PVQ3APK2HL2HNX3HP2IE/ >> Code of Conduct: http://python.org/psf/codeofconduct/ >> > _______________________________________________ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/7AUUGTM77ZJFJ4PSZUYHB2PW2VJKBYYT/ > Code of Conduct: http://python.org/psf/codeofconduct/ >
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/XJQMJU3PJ3AWOTB5MTGNHLNVAVIZG7K6/ Code of Conduct: http://python.org/psf/codeofconduct/