[Python-ideas] Function to return first(or last) true value from list

Peter Otten __peter__ at web.de
Fri Feb 21 19:00:22 CET 2014


Oscar Benjamin wrote:

> But there are also cases where that implicit behaviour is not desired.
> I would rather have to explicitly return when that's what I want so
> that the control flow is very clear.
> 
> For example when you use csv.DictReader and don't supply the
> fieldnames argument you are saying that you want to read a csv file
> with one header line containing column labels and zero or more data
> lines. To me a fully empty file (with no header line) is invalid but
> csv.DictReader will accept it as a csv file with zero rows. I would
> prefer an error in this case since it would only happen in my usage if
> an error had occurred somewhere else.

I think we constantly have to deal with libraries that do almost but not 
exactly what we want them to do. If you look at the code it is clear that 
the author made a conscious design decision

    @property
    def fieldnames(self):
        if self._fieldnames is None:
            try:
                self._fieldnames = next(self.reader)
            except StopIteration:
                pass
        self.line_num = self.reader.line_num
        return self._fieldnames

totally unrelated to for loops catching StopIterations.

You can of course easily revert that decision:

reader = csv.DictReader(...)
if reader.fieldnames is None: 
    raise EmptyCsvError

> When I use sequences and write first = seq[0] I'm deliberately
> asserting that seq is non-empty. 

> One of the examples you linked to shows exactly my own practice of
> marking a next call with a comment:
> 
>     def __next__(self):
>         while self.currkey == self.tgtkey:
>             self.currvalue = next(self.it)    # Exit on StopIteration
>             self.currkey = self.keyfunc(self.currvalue)
>         self.tgtkey = self.currkey
>         return (self.currkey, self._grouper(self.tgtkey))

> IMO if you want that behaviour then you should mark it to show that
> you thought about it and otherwise I'll treat any bare next with
> suspicion.

Similar comments are possible for obj[...]:

def heapreplace(heap, item):
    ...
    returnitem = heap[0]    # raises appropriate IndexError if heap is empty
    ...

I fail to see the fundamental difference between next(...) and 
sequence[...]. There are edge cases you have to consider, and you add 
comments where you expect them to help your readers to understand your 
intentions.





More information about the Python-ideas mailing list