Re: [Python-ideas] Add single() to itertools

2017-11-02 Thread Neil Girdhar
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

2017-10-31 Thread Cameron Simpson

On 31Oct2017 22:50, Greg Ewing  wrote:

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

2017-10-31 Thread Soni L.



On 2017-10-31 10:58 AM, Joao S. O. Bueno wrote:

On 31 October 2017 at 10:52, Steven D'Aprano  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/


___
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

2017-10-31 Thread Joao S. O. Bueno
On 31 October 2017 at 10:52, Steven D'Aprano  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/
___
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

2017-10-31 Thread Steven D'Aprano
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

2017-10-31 Thread Joao S. O. Bueno
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  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/
___
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

2017-10-31 Thread Greg Ewing




(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

2017-10-31 Thread Koos Zevenhoven
>
>
> |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

2017-10-30 Thread Chris Angelico
On Tue, Oct 31, 2017 at 3:50 PM, Ivan Pozdeev via Python-ideas
 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
>> > 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

2017-10-30 Thread Ivan Pozdeev via Python-ideas

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

2017-10-30 Thread Steven D'Aprano
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

2017-10-30 Thread Cameron Simpson

On 30Oct2017 07: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?


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

2017-10-30 Thread Guido van Rossum
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

2017-10-30 Thread Stéfane Fermigier
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'Aprano 
wrote:

> 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

2017-10-29 Thread Steven D'Aprano
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

2017-10-29 Thread Ivan Pozdeev via Python-ideas
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/