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-... is the most recent occasion where I had this use case (that is not Python but the concept is language-agnostic). -- Regards, Ivan
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 "<stdin>", line 1, in <module> 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
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.Que... ). Regards, S. On Mon, Oct 30, 2017 at 5:51 AM, Steven D'Aprano <steve@pearwood.info> 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 "<stdin>", line 1, in <module> 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&OSS 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
participants (3)
-
Ivan Pozdeev
-
Steven D'Aprano
-
Stéfane Fermigier