Check the thread https://mail.python.org/archives/list/python-ideas@python.org/thread/REYDJFCXQNQG4SAWKELQMCGM77IZG47Q/#CGMWPLJME4ZZNGHDY4DGCSF347VBMAKZ
There are comments in favor of both first and one. On Tue, Jul 28, 2020 at 3:59 PM Noam Yorav-Raphael <noamr...@gmail.com> wrote: > Thanks! It's good to hear that you too find it useful. > > Since adding methods to built-in types is much heavier than adding one > function to a module, l suggest keeping this discussion focused on adding > just the one() function to itertools, and see if there is enough support > for this. > > Cheers, > Noam > > On Tue, Jul 28, 2020 at 10:47 PM Alex Hall <alex.moj...@gmail.com> wrote: > >> In my personal toolbox of utility functions, this is by far the function >> I use most often, although it's implemented slightly differently and I call >> it `only`. I think it's very useful and it would be great to have in the >> standard library to encourage people to write safer code. >> >> Often this is part of a larger expression, especially if I'm drilling >> into some nested data structure. This can lead to having a prefix operation >> (the function call) breaking a chain of postfix operations (attributes, >> method calls, subscripting...) which is ugly and less readable. It would be >> nice if this could also be available as a method on lists, tuples, and sets >> to keep the data flowing left to right. Plus it would save an import. >> >> On Tue, Jul 28, 2020 at 9:29 PM Noam Yorav-Raphael <noamr...@gmail.com> >> wrote: >> >>> Hello, >>> >>> There's a simple function that I use many times, and I think may be a >>> good fit to be added to itertools. A function that gets an iterator, and if >>> it has exactly one element returns it, and otherwise raises an exception. >>> This is very useful for cases where I do some sort of query that I expect >>> to get exactly one result, and I want an exception to be raised if I'm >>> wrong. For example: >>> >>> jack = one(p for p in people if p.id == '1234') >>> >>> sqlalchemy already has such a function for queries: >>> https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.one >>> >>> more-itertools has this exact function: >>> >>> https://more-itertools.readthedocs.io/en/latest/api.html#more_itertools.one >>> >>> Here is a simple implementation: >>> >>> def one(iterable): >>> it = iter(iterable) >>> try: >>> first = next(it) >>> except StopIteration: >>> raise ValueError("Iterator is empty") >>> try: >>> second = next(it) >>> except StopIteration: >>> return first >>> else: >>> raise ValueError("Iterator has more than one item") >>> >>> I brought this up on python-dev, but it should be discussed here. >>> Here is the discussion: >>> >>> https://mail.python.org/archives/list/python-...@python.org/thread/D52MPKLIN4VEXBOCKVMTWAK66MAOEINY/ >>> >>> Brett Cannon said that this idea has been brought up at least twice >>> before. I found: >>> >>> https://mail.python.org/archives/list/python-ideas@python.org/thread/FTJ6JRDTZ57HUVZ3PVIZV2NHU2NLAC4X/#RMWV3SNZ2N4KZLPKPIDE42H46QDEIVHE >>> >>> >>> https://mail.python.org/archives/list/python-ideas@python.org/thread/REYDJFCXQNQG4SAWKELQMCGM77IZG47Q/#ITR2ILPVCKYR52U2D7RHGENASZTNVDHN >>> >>> The first thread hasn't reached any operative conclusion. The second >>> thread was very long, and seemed to focus mostly on another function, >>> first(), that doesn't check if there is more than one item. Joao S. O Bueno >>> said that it passed "general approval". I think that perhaps a new >>> discussion, focused just on one (no pun intended) function in the itertools >>> module may reach a conclusion. >>> >>> It was suggested that instead of an additional function, one can use >>> iterator unpacking: >>> >>> jack, = (p for p in people if p.id == '1234') >>> or >>> [jack] = (p for p in people if p.id == '1234') >>> >>> I still think that having a one() function would be useful, since: >>> 1. I think it spells the intention more clearly. It is not symbols that >>> you need to understand their meaning in order to understand that I expect >>> the iterable to have exactly one item, it's spelled in code. >>> 2. The exception would be easier to understand, since errors in tuple >>> unpacking usually mean something else. >>> 3. The one() function allows you to use the result inside an expression >>> without assigning it to a variable. Therefore, I think it encourages >>> writing better code. It's very easy to write: >>> print([p for p in people if p.id == '1234][0]) >>> (which has the problem of not verifying the assumption that there's no >>> more than one result), and I find it easier to replace _[0] with one(_) >>> than to be required to name a new variable, and instead of having an >>> operation on the iterable, change the way I'm assigning to it. >>> >>> WDYT? >>> >>> Cheers, >>> Noam >>> >>> >>> _______________________________________________ >>> Python-ideas mailing list -- python-ideas@python.org >>> To unsubscribe send an email to python-ideas-le...@python.org >>> https://mail.python.org/mailman3/lists/python-ideas.python.org/ >>> Message archived at >>> https://mail.python.org/archives/list/python-ideas@python.org/message/6OLEL4XTUWXRI7ENODKEDOYFBRVDYKI7/ >>> Code of Conduct: http://python.org/psf/codeofconduct/ >>> >> _______________________________________________ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/RKRPD5DXG3GOXHGVJFTAURFY3XROQHBK/ > Code of Conduct: http://python.org/psf/codeofconduct/ > -- Sebastian Kreft
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/WIGGAB57L75RFCFY6XF5BNJOHXD2F3YB/ Code of Conduct: http://python.org/psf/codeofconduct/