Pythonic style

Frank Millman frank at chagford.com
Mon Sep 21 10:44:19 EDT 2020


On 2020-09-21 3:46 PM, Chris Angelico wrote:
> On Mon, Sep 21, 2020 at 11:37 PM Tim Chase
> <python.list at tim.thechases.com> wrote:
>>
>> On 2020-09-20 18:34, Stavros Macrakis wrote:
>>> Consider a simple function which returns the first element of an
>>> iterable if it has exactly one element, and throws an exception
>>> otherwise. It should work even if the iterable doesn't terminate.
>>> I've written this function in multiple ways, all of which feel a
>>> bit clumsy.
>>>
>>> I'd be interested to hear thoughts on which of these solutions is
>>> most Pythonic in style. And of course if there is a more elegant
>>> way to solve this, I'm all ears! I'm probably missing something
>>> obvious!
>>
>> You can use tuple unpacking assignment and Python will take care of
>> the rest for you:
>>
>>    >>> x, = tuple() # no elements
>>    Traceback (most recent call last):
>>      File "<stdin>", line 1, in <module>
>>    ValueError: not enough values to unpack (expected 1, got 0)
>>    >>> x, = (1, )  # one element
>>    >>> x, = itertools.repeat("hello") # 2 to infinite elements
>>    Traceback (most recent call last):
>>      File "<stdin>", line 1, in <module>
>>    ValueError: too many values to unpack (expected 1)
>>
>> so you can do
>>
>>    def fn(iterable):
>>      x, = iterable
>>      return x
>>
>> The trailing comma can be hard to spot, so I usually draw a little
>> extra attention to it with either
>>
>>    (x, ) = iterable
>>
>> or
>>
>>    x, = iterable # unpack one value
>>
>> I'm not sure it qualifies as Pythonic, but it uses Pythonic features
>> like tuple unpacking and the code is a lot more concise.
> 
> Or:
> 
> [x] = iterable
> 
> I'd definitely recommend using unpacking as the most obvious way to do
> this. Among other advantages, it gives different messages for the "too
> many" and "too few" cases.
> 

I used something similar years ago, but I made the mistake of relying on 
the error message in my logic, to distinguish between 'too few' and 'too 
many'. Guess what happened - Python changed the wording of the messages, 
and my logic failed.

After messing about with some alternatives, I ended up with the OP's 
first option (with some added comments), and have stuck with it ever 
since. It is not pretty, but it is readable and unambiguous.

Frank Millman


More information about the Python-list mailing list