[Python-ideas] Aid reiteration with new class: gfic
steve at pearwood.info
Fri Jun 19 05:11:11 CEST 2009
On Fri, 19 Jun 2009 07:02:12 am Terry Reedy wrote:
> Most functions that take an iterable as parameter iterate just once.
> Users of the function can pass any iterable, including iterators.
> The function will call iter(imput) and go.
> If the user wants to iterate thru a virtual collection defined by an
> instance of an iterator class (built-in or user-defined) or generator
> function, the user must call the gf/ic with the appropriate arguments
> and pass the result.
I don't think it's an undue burden on the caller to construct their own
iterator before calling your function.
To summarise your idea (correct me if I'm wrong):
There are three ways of passing iterable-like arguments:
(A) pass a sequence object like lists;
(B) pass generators or iterators;
(C) pass a constructor which returns a generator or iterator, plus
Insider your function, you can easily iterate over (A) or (C) multiple
times, but not (B).
I don't think there's any way to treat all three cases identically. Your
proposed gfic class will allow you to treat case (C) just like (A), at
the cost of expecting the caller to call gfic() rather than pass a
constructor directly. But the caller still can't pass an iterator in
place of a sequence or constructor, so you haven't solved anything,
merely shifted the burden on the user from calling one of:
to calling one of:
function(gfic(constructor, *args, **kwargs))
As I see it, the correct solution for "my function needs to iterate over
an iterable twice" is not to expect the caller to pass a sequence, but
to convert the iterable to a sequence inside your function:
# Iterate over iterable twice
L = list(iterable)
for _ in (1, 2):
for x in L:
Apart from needing to knowing to avoid non-terminating iterators, the
user need not know whether you walk the input once or twice.
I suppose there is some benefit when dealing with huge iterators, but
that's probably best dealt with on an ad hoc basis by requiring the
user to pass a constructor directly.
More information about the Python-ideas