Coding style
Terry Reedy
tjreedy at udel.edu
Tue Jul 18 22:24:09 EDT 2006
"Patrick Maupin" <pmaupin at gmail.com> wrote in message
news:1153240327.611631.76600 at h48g2000cwc.googlegroups.com...
>
> Carl Banks wrote:
>> def process_values(lst):
>> if not lst:
>> return
>> do_expensive_initialization_step()
>> for item in lst:
>> do_something_with(item)
>> do_expensive_finalization_step()
>> What if you called the function like this:
>>
>> process_values(x.strip() for x in values_lst)
> The perverse wish, expressed in the specific example, that SOME piece
> of code SOMEWHERE should PLEASE throw an exception because some idiot
> passed a generator expression rather than a list into a function, is
> not apt to be well received by an audience which strives for generality
> when it makes sense; and I daresay most members of that audience, if
> confronted with the wished-for exception, would fix the function so
> that it quite happily accepted generator expressions, rather than
> changing a conditional to use len() just so that an equivalent
> exception could happen a bit earlier.
Given that the input is going to be scanned by an iterator, it really makes
sense to me to accept an iterator as input. (Unless the function is for
special-case usage in a predefined, never to be expanded, set of
circumstances in which such generality is not needed. In such a case, if
lst: is no problem.) I think the following, untested rewrite suffices.
def process_values(lst):
it = iter(lst)
try:
item = it.next()
do_expensive_initialization_step()
do_something_with(item) # see note
for item in it:
do_something_with(item)
do_expensive_finalization_step()
except StopIteration:
pass # or any special empty input code
# note: if writing do_something_with(item) is bothersome,
# replace 3 lines with
while True:
do_something_with(item)
try:
item = it.next
except StopIteration:
break
In general, to work with iterators instead of containers, change
if container:
do_stuff()
else:
do_empty()
to
try:
item = it.next()
do_modified_stuff() # taking into account that have item already
except StopIteration:
do_empty()
Guido has so far vetoed adding .__len__() to the iterator protocol because
a) it is not always possible and b) he want to keep the protocol as simple
as it is.
Terry Jan Reedy
More information about the Python-list
mailing list