[Python-ideas] Aid reiteration with new class: gfic
Terry Reedy
tjreedy at udel.edu
Fri Jun 19 08:38:30 CEST 2009
Steven D'Aprano wrote:
> On Fri, 19 Jun 2009 07:02:12 am Terry Reedy wrote:
>> Backgound:
>> 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.
Only if an iterator is not allowed.
Nor do I think it an undue burden either to wrap the constructor, when
appropriate, instead of calling it.
> 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
> appropriate arguments.
Right.
>
> 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),
That is precisely the point.
> at
> the cost of expecting the caller to call gfic() rather than pass a
> constructor directly.
See above
> 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:
>
> function(list(constructor(*args, **kwargs)))
> function(list(iterator))
>
> to calling one of:
>
> function(gfic(constructor, *args, **kwargs))
> function(list(iterator))
Right. I consider list-avoidance a good thing, more so, it appears than
you ;-).
>
> 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:
>
> def function(iterable):
> # Iterate over iterable twice
> L = list(iterable)
> for _ in (1, 2):
> for x in L:
> pass
>
> 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.
Thank you for your response and analysis.
tjr
More information about the Python-ideas
mailing list