Re: [Python-ideas] Add single() to itertools
This request is called "one" in more-itertools: http://more-itertools.readthedocs.io/en/latest/api.html It raises ValueError as Steve suggested. On Monday, October 30, 2017 at 8:34:26 AM UTC-6, Guido van Rossum wrote: > > This is a key example of a case where code speaks. Can you write an > implementation of how you would want single() to work in Python code? > > On Mon, Oct 30, 2017 at 2:49 AM, Ivan Pozdeev via Python-ideas < > python...@python.org > wrote: > >> >> >> On 30.10.2017 9:29, python-ide...@python.org wrote: >> >>> If I have understood your use-case, you have a function that returns a >>> list of results (or possibly an iterator, or a tuple, or some other >>> sequence): >>> >>> print(search(haystack, needle)) >>> # prints ['bronze needle', 'gold needle', 'silver needle'] >>> >>> There are times you expect there to be a single result, and if there are >>> multiple results, that is considered an error. Am I correct so far? >>> >> Correct. >> >>> If so, then sequence unpacking is your friend: >>> >>> result, = search(haystack, needle) >>> >>> <...> >>> >>> I *think* this will solve your problem. >>> >>> If not, can you please explain what "single()" is supposed to do, why it >>> belongs in itertools, and show an example of how it will work. >>> >> That works. Too arcane in my book though (and others' too according to >> https://stackoverflow.com/a/473337/648265), and the error messages are >> cryptic in this use case. >> It also cannot be a part of an expression, unlike next(). >> >> The initial post on the above link summarizes the suggested >> implementation pretty well. >> >> -- >> Regards, >> Ivan >> >> >> ___ >> Python-ideas mailing list >> python...@python.org >> https://mail.python.org/mailman/listinfo/python-ideas >> Code of Conduct: http://python.org/psf/codeofconduct/ >> > > > > -- > --Guido van Rossum (python.org/~guido) > ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add single() to itertools
On 31Oct2017 22:50, Greg Ewingwrote: Koos Zevenhoven wrote: |defsingle(i): try: ||v =i.next() |||exceptStopIteration:raiseException('No values')|||try: ||i.next() ||exceptStopIteration: ||returnv||else: ||raiseException('Too many values')|||printsingle(name forname in('bob','fred')ifname=='bob')||| | Looks like a clever method of whitespace compression to me. Those narrow vertical bars take up far less room that spaces! And so convenient! No dependency on some parochial indentation size policy. - Cameron ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add single() to itertools
On 2017-10-31 10:58 AM, Joao S. O. Bueno wrote: On 31 October 2017 at 10:52, Steven D'Apranowrote: On Tue, Oct 31, 2017 at 10:42:23AM -0200, Joao S. O. Bueno wrote: When I need something like this, I usually rop a line on the module namespace that goes like: first = lambda x: next(iter(x)) That doesn't meet the requirement that x has ONLY one item. And using lambda like that is bad style. This would be better: def first(x): return next(iter(x)) and now first has a proper __name__. I know that. But then, I'd rather write it as 3-4 lines in some utils module. So, although I was initially -1 to -0 on this suggestion, maybe it has a point. Plop this one-liner somewhere: exec('def single(x):\n [v] = x\n return v') -- Steve ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/ ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/ ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add single() to itertools
On 31 October 2017 at 10:52, Steven D'Apranowrote: > On Tue, Oct 31, 2017 at 10:42:23AM -0200, Joao S. O. Bueno wrote: >> When I need something like this, I usually rop a line on the module >> namespace that goes like: >> >> first = lambda x: next(iter(x)) > > That doesn't meet the requirement that x has ONLY one item. > > And using lambda like that is bad style. This would be better: > > def first(x): return next(iter(x)) > > and now first has a proper __name__. I know that. But then, I'd rather write it as 3-4 lines in some utils module. So, although I was initially -1 to -0 on this suggestion, maybe it has a point. > > > > -- > Steve > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add single() to itertools
On Tue, Oct 31, 2017 at 10:42:23AM -0200, Joao S. O. Bueno wrote: > When I need something like this, I usually rop a line on the module > namespace that goes like: > > first = lambda x: next(iter(x)) That doesn't meet the requirement that x has ONLY one item. And using lambda like that is bad style. This would be better: def first(x): return next(iter(x)) and now first has a proper __name__. -- Steve ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add single() to itertools
When I need something like this, I usually rop a line on the module namespace that goes like: first = lambda x: next(iter(x)) On 30 October 2017 at 23:09, Steven D'Apranowrote: > On Tue, Oct 31, 2017 at 07:51:02AM +1100, Cameron Simpson wrote: > >> return the(nodes) >> >> It's this kind of thing that expresses my intent better than the: >> >> node, = nodes >> return node >> >> idiom. > > If the intent is to indicate that there is only one node, then > "the(nodes)" fails completely. "The" can refer to plurals as easily as > singular: > > "Wash the dirty clothes." > (Later) "Why did you only wash one sock?" > > > The simplest implementation of this "single()" function I can think of > would be: > > def single(iterable): > result, = iterable > return result > > > That raises ValueError if iterable has too few or too many items, which > I believe is the right exception to use. Conceptually, there's no > indexing involved, so IndexError would be the wrong exception to use. > We're expecting a compound value (an iterable) with exactly one item. If > there's not exactly one item, that's a ValueError. > > > > -- > Steve > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add single() to itertools
(Reposting this to list -- pushed wrong reply button!) Koos Zevenhoven wrote: |defsingle(i): try: ||v =i.next() |||exceptStopIteration:raiseException('No values')|||try: ||i.next() ||exceptStopIteration: ||returnv||else: ||raiseException('Too many values')|||printsingle(name forname in('bob','fred')ifname=='bob')||| | Looks like a clever method of whitespace compression to me. Those narrow vertical bars take up far less room that spaces! -- Greg ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add single() to itertools
> > > |defsingle(i): try: ||v =i.next() > |||exceptStopIteration:raiseException('No > values')|||try: ||i.next() ||exceptStopIteration: ||returnv||else: > ||raiseException('Too many values')| > ||printsingle(name forname in('bob','fred')ifname=='bob')||| | > > Now that looks seriously weird. Oh wait, I know, it must be a regular expression! Perhaps mixed with Perl? To figure out what it does, we could try compiling it and throwing input at it, or perhaps more simply by just reverse engineering the implementation. ––Koos -- + Koos Zevenhoven + http://twitter.com/k7hoven + ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add single() to itertools
On Tue, Oct 31, 2017 at 3:50 PM, Ivan Pozdeev via Python-ideaswrote: > On 30.10.2017 17:32, Guido van Rossum wrote: >> >> This is a key example of a case where code speaks. Can you write an >> implementation of how you would want single() to work in Python code? >> >> On Mon, Oct 30, 2017 at 2:49 AM, Ivan Pozdeev via Python-ideas >> > wrote: >> >> The initial post on the above link summarizes the suggested >> implementation pretty well. >> > |defsingle(i): try: ||v =i.next() > |||exceptStopIteration:raiseException('No values')|||try: ||i.next() > ||exceptStopIteration: ||returnv||else: ||raiseException('Too many values')| > ||printsingle(name forname in('bob','fred')ifname=='bob')||| | > > || raise WhitespaceDamagedException from None ChrisA ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add single() to itertools
On 30.10.2017 17:32, Guido van Rossum wrote: This is a key example of a case where code speaks. Can you write an implementation of how you would want single() to work in Python code? On Mon, Oct 30, 2017 at 2:49 AM, Ivan Pozdeev via Python-ideas> wrote: The initial post on the above link summarizes the suggested implementation pretty well. |defsingle(i): try: ||v =i.next() |||exceptStopIteration:raiseException('No values')|||try: ||i.next() ||exceptStopIteration: ||returnv||else: ||raiseException('Too many values')| ||printsingle(name forname in('bob','fred')ifname=='bob')||| | || -- Regards, Ivan ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add single() to itertools
On Tue, Oct 31, 2017 at 07:51:02AM +1100, Cameron Simpson wrote: > return the(nodes) > > It's this kind of thing that expresses my intent better than the: > > node, = nodes > return node > > idiom. If the intent is to indicate that there is only one node, then "the(nodes)" fails completely. "The" can refer to plurals as easily as singular: "Wash the dirty clothes." (Later) "Why did you only wash one sock?" The simplest implementation of this "single()" function I can think of would be: def single(iterable): result, = iterable return result That raises ValueError if iterable has too few or too many items, which I believe is the right exception to use. Conceptually, there's no indexing involved, so IndexError would be the wrong exception to use. We're expecting a compound value (an iterable) with exactly one item. If there's not exactly one item, that's a ValueError. -- Steve ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add single() to itertools
On 30Oct2017 07:32, Guido van Rossumwrote: This is a key example of a case where code speaks. Can you write an implementation of how you would want single() to work in Python code? Myself, I'm not advocating for putting such a thing in itertools. However, I do have an equivalent utility function of my own that makes for more readable code, named "the". It sees far less use than I'd imagined it would, but it does read nicely to my eye when used. I have a few select-something from data where there _can_ be multiple hits i.e. the data format/structure support multiple matching results, but the caller's use case requires just one hit or failure. So I have some fuzzy-db-lookup functions which end with: return the(rows) or include: row = the(rows) and some HTML find-this-DOM-node code which ends with: return the(nodes) It's this kind of thing that expresses my intent better than the: node, = nodes return node idiom. And as remarked, you can embed the() in an expression. I don't think it ranks in "belongs in the stdlib". I do keep it about in a module for ready use though. If nothing else, it raises IndexErrors with distinct text for 0 and >1 failure. Cheers, Cameron Simpson (formerly c...@zip.com.au) ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add single() to itertools
This is a key example of a case where code speaks. Can you write an implementation of how you would want single() to work in Python code? On Mon, Oct 30, 2017 at 2:49 AM, Ivan Pozdeev via Python-ideas < python-ideas@python.org> wrote: > > > On 30.10.2017 9:29, python-ideas-requ...@python.org wrote: > >> If I have understood your use-case, you have a function that returns a >> list of results (or possibly an iterator, or a tuple, or some other >> sequence): >> >> print(search(haystack, needle)) >> # prints ['bronze needle', 'gold needle', 'silver needle'] >> >> There are times you expect there to be a single result, and if there are >> multiple results, that is considered an error. Am I correct so far? >> > Correct. > >> If so, then sequence unpacking is your friend: >> >> result, = search(haystack, needle) >> >> <...> >> >> I *think* this will solve your problem. >> >> If not, can you please explain what "single()" is supposed to do, why it >> belongs in itertools, and show an example of how it will work. >> > That works. Too arcane in my book though (and others' too according to > https://stackoverflow.com/a/473337/648265), and the error messages are > cryptic in this use case. > It also cannot be a part of an expression, unlike next(). > > The initial post on the above link summarizes the suggested implementation > pretty well. > > -- > Regards, > Ivan > > > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > -- --Guido van Rossum (python.org/~guido) ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add single() to itertools
IIUC, this would be similar to "first" ( https://pypi.python.org/pypi/first/ ) but would raise exception in case the iterable returns more than one (or less than one) element. Would also be similar to one() in SQLAlchemy queries ( http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.one ). Regards, S. On Mon, Oct 30, 2017 at 5:51 AM, Steven D'Apranowrote: > On Mon, Oct 30, 2017 at 07:14:10AM +0300, Ivan Pozdeev via Python-ideas > wrote: > > > The eponymous C#'s LINQ method, I found very useful in the following, > > quite recurring use-case: > > If I have understood your use-case, you have a function that returns a > list of results (or possibly an iterator, or a tuple, or some other > sequence): > > print(search(haystack, needle)) > # prints ['bronze needle', 'gold needle', 'silver needle'] > > There are times you expect there to be a single result, and if there are > multiple results, that is considered an error. Am I correct so far? > > If so, then sequence unpacking is your friend: > > result, = search(haystack, needle) > > Note the comma after the variable name on the left-hand side of the > assignment. That's a special case of Python's more general sequence > unpacking: > > a, b, c = [100, 200, 300] > > assigns a = 100, b = 200, c == 300. Using a single item is valid: > > py> result, = [100] > py> print(result) > 100 > > > but if the right-hand side has more than one item, you get an exception: > > py> result, = [100, 200, 300] > Traceback (most recent call last): > File "", line 1, in > ValueError: too many values to unpack (expected 1) > > > I *think* this will solve your problem. > > If not, can you please explain what "single()" is supposed to do, why it > belongs in itertools, and show an example of how it will work. > > > -- > Steve > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > -- Stefane Fermigier - http://fermigier.com/ - http://twitter.com/sfermigier - http://linkedin.com/in/sfermigier Founder & CEO, Abilian - Enterprise Social Software - http://www.abilian.com/ Chairman, Free Group / Systematic Cluster - http://www.gt-logiciel-libre.org/ Co-Chairman, National Council for Free & Open Source Software (CNLL) - http://cnll.fr/ Founder & Organiser, PyData Paris - http://pydata.fr/ --- “You never change things by fighting the existing reality. To change something, build a new model that makes the existing model obsolete.” — R. Buckminster Fuller ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add single() to itertools
On Mon, Oct 30, 2017 at 07:14:10AM +0300, Ivan Pozdeev via Python-ideas wrote: > The eponymous C#'s LINQ method, I found very useful in the following, > quite recurring use-case: If I have understood your use-case, you have a function that returns a list of results (or possibly an iterator, or a tuple, or some other sequence): print(search(haystack, needle)) # prints ['bronze needle', 'gold needle', 'silver needle'] There are times you expect there to be a single result, and if there are multiple results, that is considered an error. Am I correct so far? If so, then sequence unpacking is your friend: result, = search(haystack, needle) Note the comma after the variable name on the left-hand side of the assignment. That's a special case of Python's more general sequence unpacking: a, b, c = [100, 200, 300] assigns a = 100, b = 200, c == 300. Using a single item is valid: py> result, = [100] py> print(result) 100 but if the right-hand side has more than one item, you get an exception: py> result, = [100, 200, 300] Traceback (most recent call last): File "", line 1, in ValueError: too many values to unpack (expected 1) I *think* this will solve your problem. If not, can you please explain what "single()" is supposed to do, why it belongs in itertools, and show an example of how it will work. -- Steve ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Add single() to itertools
The eponymous C#'s LINQ method, I found very useful in the following, quite recurring use-case: I need to get a specific element from a data structure that only supports search semantics (i.e. returns a sequence/iterator of results). For that, I specify very precise search criteria, so only that one item is supposed to be found. But I'd rather verify that just in case. "A data structure that only supports search semantics" is a recurring phenomenon due to this: I make a special-purpose data structure (usually for some domain-specific data like task specification or data directory) using a combination of existing and/or new containers. Now, these types do not enforce all the integrity constraints of my data. And I don't wish to construct a special-purpose class, complete with validation procedures, and pass records into it one by one etc -- when I can just write an initializer, loading all the data at once in a nicely readable construct, and call it a day. So, when querying this structure, I "know" that there should only be one item satisfying a certain criteria - if there's more, or less, something is wrong with the data. https://stackoverflow.com/questions/46009985/get-contentcontrol-by-title-or-tag is the most recent occasion where I had this use case (that is not Python but the concept is language-agnostic). -- Regards, Ivan ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/