Re: [Python-ideas] Add single() to itertools
On 30.10.2017 9:29, python-ideas-request@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
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-request@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)
On 30Oct2017 07:32, Guido van Rossum <guido@python.org> 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?
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 <cs@cskk.id.au> (formerly cs@zip.com.au)
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
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'Aprano <steve@pearwood.info> wrote:
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/
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
On 31 October 2017 at 10:52, Steven D'Aprano <steve@pearwood.info> wrote:
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/
On 2017-10-31 10:58 AM, Joao S. O. Bueno wrote:
On 31 October 2017 at 10:52, Steven D'Aprano <steve@pearwood.info> wrote:
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/
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 <python-ideas@python.org <mailto:python-ideas@python.org>> 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
On Tue, Oct 31, 2017 at 3:50 PM, Ivan Pozdeev via Python-ideas <python-ideas@python.org> wrote:
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 <python-ideas@python.org <mailto:python-ideas@python.org>> 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
|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 +
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 <javascript:>> wrote:
On 30.10.2017 9:29, python-ide...@python.org <javascript:> 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 <javascript:> https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido)
participants (9)
-
Cameron Simpson
-
Chris Angelico
-
Guido van Rossum
-
Ivan Pozdeev
-
Joao S. O. Bueno
-
Koos Zevenhoven
-
Neil Girdhar
-
Soni L.
-
Steven D'Aprano