On 2020-09-21 3:46 PM, Chris Angelico wrote:
On Mon, Sep 21, 2020 at 11:37 PM Tim Chase
<python.l...@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

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to