<div>This could be generalized and placed into itertools if we create a function (say, apply for lack of a better name at the moment) that takes in an iterable and creates new iterables that yield each from the original (avoiding the need for a list) holding only one in memory. Then you could pass the whatever function you wanted to run the iterables over an get the result back in a tuple.</div>
<div><br></div><div>Eg:</div><div><br></div><div>itertools.apply(iterable, min, max) ~= (min(iterable), max(iterable))</div><div><br></div><div>This class that creates 'associated iterables' from an original iterable where each new iterable has to be iterated over at the same time might also be useful in other contexts and could be added to itertools as well.</div>
<div><br></div><div><br></div><div>Unfortunately this solution seems incompatable with the implementations with for loops in min and max (EG: How do you switch functions at the right time?) So it might take some tweaking.</div>
<div><br></div>--<br clear="all">Zachary Burns<br>(407)590-4814<br>Aim - Zac256FL<br><br>
<br><br><div class="gmail_quote">On Sun, Oct 10, 2010 at 4:17 PM, Steven D'Aprano <span dir="ltr"><<a href="mailto:steve@pearwood.info">steve@pearwood.info</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
On Mon, 11 Oct 2010 05:57:21 am Paul McGuire wrote:<br>
> Just as an exercise, I wanted to try my hand at adding a function to<br>
> the compiled Python C code.  An interesting optimization that I read<br>
> about (where? don't recall) finds the minimum and maximum elements of<br>
> a sequence in a single pass, with a 25% reduction in number of<br>
> comparison operations:<br>
> - the sequence elements are read in pairs<br>
> - each pair is compared to find smaller/greater<br>
> - the smaller is compared to current min<br>
> - the greater is compared to current max<br>
><br>
> So each pair is applied to the running min/max values using 3<br>
> comparisons, vs. 4 that would be required if both were compared to<br>
> both min and max.<br>
><br>
> This feels somewhat similar to how divmod returns both quotient and<br>
> remainder of a single division operation.<br>
><br>
> This would be potentially interesting for those cases where min and<br>
> max are invoked on the same sequence one after the other, and<br>
> especially so if the sequence elements were objects with expensive<br>
> comparison operations.<br>
<br>
Perhaps more importantly, it is ideal for the use-case where you have an<br>
iterator. You can't call min() and then max(), as min() consumes the<br>
iterator leaving nothing for max(). It may be undesirable to convert<br>
the iterator to a list first -- it may be that the number of items in<br>
the data stream is too large to fit into memory all at once, but even<br>
if it is small, it means you're now walking the stream three times when<br>
one would do.<br>
<br>
To my mind, minmax() is as obvious and as useful a built-in as divmod(),<br>
but if there is resistance to making such a function a built-in,<br>
perhaps it could go into itertools. (I would prefer it to keep the same<br>
signature as min() and max(), namely that it will take either a single<br>
iterable argument or multiple arguments.)<br>
<br>
I've experimented with minmax() myself. Not surprisingly, the<br>
performance of a pure Python version doesn't even come close to the<br>
built-ins.<br>
<br>
I'm +1 on the idea.<br>
<br>
Presumably follow-ups should go to python-ideas.<br>
<font color="#888888"><br>
<br>
<br>
--<br>
Steven D'Aprano<br>
_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org">Python-ideas@python.org</a><br>
<a href="http://mail.python.org/mailman/listinfo/python-ideas" target="_blank">http://mail.python.org/mailman/listinfo/python-ideas</a><br>
</font></blockquote></div><br>