[Python-ideas] Generator unpacking

Andrew Barnert abarnert at yahoo.com
Sat Feb 13 13:00:53 EST 2016


On Feb 13, 2016, at 08:36, Oscar Benjamin <oscar.j.benjamin at gmail.com> wrote:
> 
>> On 13 February 2016 at 13:06, Nick Coghlan <ncoghlan at gmail.com> wrote:
>> 1. The cases where you actually want "unpack this many values, ignore
>> the rest" are pretty rare
> 
> It's not so much ignore the rest but rather retain the rest for
> separate consumption. This happens when you want to either peek or
> split the first item. For example in parsing a csv file:
> 
> def readcsv(csvfile):
>    csvfile = map(str.split, csvfile)
>    try:
>        fieldnames = next(csvfile)
>    except StopIteration:
>        raise ValueError('Bad csv file')
>    return [dict(zip(fieldnames, line)) for line in csvfile]
> 
> It would be nicer to write that as something like
> 
>    fieldnames, * = csvfile

So instead of getting an exception that says "bad csv file" you get one that says "unpacking expected at least 1 value, found 0" or something? That doesn't seem nicer.

But if we really do need such functionality commonly, just adding an exception type parameter to next would cover it. Or just putting an exception-wrapping function in the stdlib, so you can just write "fieldnames = exwrap(next, StopIteration, ValueError)(csvfile)". But then anyone can write exwrap as a three-line function today, and I don't think anyone ever does, so I doubt it needs to be standardized...

Also, is it worth mentioning that this doesn't actually parse csv files, but whitespace-separated files, without any form of escaping or quoting, and probably doing the wrong thing on short rows? Because there is a really easy way of writing this function that's a lot nicer and a lot shorter and raises meaningful exceptions and actually works: 

    def readcsv(csvfile):
        return list(csv.DictReader(csvfile))

(Although I'm not sure why you want a list rather than an iterator in the first place.)

> Another situation where I've wanted that is given an iterable that
> yields sequences all of the same length I might want to peek the first
> item to check its length before the loop begins.

Again, next.

>> 2. When you do really need it, islice handles it
> 
> That's true so you can do
> 
>    fieldnames, = islice(csvfile, 1)
> 
> Somehow I don't like that but really it's fine.


More information about the Python-ideas mailing list