On Wed, 15 Jun 2022 at 04:07, Travis Griggs <travisgri...@gmail.com> wrote: > def mapFirst(stream, transform): > try: > first = next(stream) > except StopIteration: > return > yield transform(first) > yield from stream
Small suggestion: Begin with this: stream = iter(stream) That way, you don't need to worry about whether you're given an iterator or some other iterable (for instance, you can't call next() on a list, but it would make good sense to be able to use your function on a list). (BTW, Python's convention would be to call this "map_first" rather than "mapFirst". But that's up to you.) > def mapLast(stream, transform): > try: > previous = next(stream) > except StopIteration: > return > for item in stream: > yield previous > previous = item > yield transform(previous) Hmm. This might be a place to use multiple assignment, but what you have is probably fine too. > def main(): > for each in (iterEmpty, iter1, iter2, iterMany): > baseIterator = each() > chopFirst = mapFirst(baseIterator, lambda x: x[1:-1]) > andCapLast = mapLast(chopFirst, lambda x: x.upper()) > print(repr(" ".join(andCapLast))) Don't bother with a main() function unless you actually need to be able to use it as a function. Most of the time, it's simplest to just have the code you want, right there in the file. :) Python isn't C or Java, and code doesn't have to get wrapped up in functions in order to exist. > Is this idiomatic? Especially my implementations of mapFirst and mapList > there in the middle? Or is there some way to pull this off that is more > elegant? > Broadly so. Even with the comments I've made above, I wouldn't say there's anything particularly *wrong* with your code. There are, of course, many ways to do things, and what's "best" depends on what your code is doing, whether it makes sense in context. > I've been doing more with iterators and stacking them (probably because I've > been playing with Elixir elsewhere), I am generally curious what the > performance tradeoffs of heavy use of iterators and yield functions in python > is. I know the argument for avoiding big list copies when moving between > stages. Is it one of those things where there's also some overhead with them, > where for small stuff, you'd just be better list-ifying the first iterator > and then working with lists (where, for example, I could do the first/last > clamp operation with just indexing operations). > That's mostly right, but more importantly: Don't worry about performance. Worry instead about whether the code is expressing your intent. If that means using a list instead of an iterator, go for it! If that means using an iterator instead of a list, go for it! Python won't judge you. :) But if you really want to know which one is faster, figure out a reasonable benchmark, and then start playing around with the timeit module. Just remember, it's very very easy to spend hours trying to make the benchmark numbers look better, only to discover that it has negligible impact on your code's actual performance - or, in some cases, it's *worse* than before (because the benchmark wasn't truly representative). So if you want to spend some enjoyable time exploring different options, go for it! And we'd be happy to help out. Just don't force yourself to write bad code "because it's faster". ChrisA -- https://mail.python.org/mailman/listinfo/python-list