Re: Feature request enumerate_with_rest or enumerate with skip or filter callback

Le sam. 2 oct. 2021 à 15:54, python-ideas-request@python.org a écrit :
Date: Sat, 2 Oct 2021 12:45:33 +0200 From: Laurent Lyaudet laurent.lyaudet@gmail.com Subject: [Python-ideas] Feature request enumerate_with_rest or enumerate with skip or filter callback To: python-ideas@python.org Message-ID: CAB1LBmsXQJbeLuyK6tG8aP=kb36DAR==VcajO-zHuHJGnfvAJA@mail.gmail.com Content-Type: text/plain; charset="UTF-8"
Hello,
This is a very simple feature request that does not break anything but I don't know if you may find it interesting. It would be nice to have a function or method of list objects that does this :
- First idea :
def enumerate_with_rest(my_list): for i, item in enumerate(my_list): yield i, item, my_list[:i] + my_list[i + 1:]
It could be called easily with:
for i, item, rest in enumerate_with_rest(my_list): # do something
or for i, item, rest in my_list.enumerate_with_rest(): # do something
I am not the only one who had the same need : https://stackoverflow.com/questions/56966429/getting-pairs-of-one-item-and-t...
It would be nice to have an optimized C function for this. However, it may be less interesting than this :
- Second idea
enumerate_with_rest above has quadratic complexity. It is probably true that most processes that use it will also have quadratic complexity. However, it would be better to return an iterator instead of a list for the rest, it would use less space. For this a param skip to enumerate would do the job def enumerate_with_rest(my_list): for i, item in enumerate(my_list): yield i, item, enumerate(my_list, skip=i) There could be variants of this idea like :
- enumerate(my_list, skip=i)
- enumerate(my_list, skip=[i])
- enumerate(my_list, filter_callback=(lambda x: x != i))
Please let me know what you think of it :)
Thanks for your time, best regards, Laurent Lyaudet
Hello, Regarding the last suggestion. - enumerate(my_list, filter_callback=(lambda x: x != i)) The idea is to filter a list by indices : a quick search for that just yields : https://stackoverflow.com/questions/11847491/python-filtering-lists-by-indic... which is not really helpful Since filter() returns an iterator instead of a list, it could do what is needed... if the callback had access to the index like the Javascript array filter function.
def enumerate_with_rest(my_list): for i, item in enumerate(my_list): yield i, item, my_list[:i] + my_list[i + 1:]
could also be : def enumerate_with_rest(my_list): for i, item in enumerate(my_list): yield i, item, filter_by_index(my_list, lambda x: x != i)
I think my feature request for enumerate_with_rest is maybe too specific. However, I think there should definitely be in itertools something to filter indices like JS permits. I have not found a function to do this there: https://docs.python.org/3/library/functions.html https://docs.python.org/3/library/itertools.html What would be your prefered way of doing this ? enumerate(my_list, filter_callback=(lambda x: x != i)) filter_by_index(my_list, lambda x: x != i) # à la JS filter(my_list, lambda _, x: x != i)
Currently, the following solution is available : filter(enumerate(my_list), lambda x: x[0] != i) But it is slightly ugly and unefficient to have two function calls for such a simple task I think. I would appreciate any feedback; even if none of my ideas are accepted, I may learn something :)
Best regards, Laurent Lyaudet

Hi Laurent,
It is not clear to me what you mean by "filter by indices".
On Sat, Oct 02, 2021 at 10:25:05PM +0200, Laurent Lyaudet wrote:
The idea is to filter a list by indices :
[...]
Since filter() returns an iterator instead of a list, it could do what is needed... if the callback had access to the index like the Javascript array filter function.
Do you mean this?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Obj...
You shouldn't assume we are all experts on Javascript :-)
If that is what you want, it is easy to get access to the index. We can just do:
filter(function, enumerate(items))
and so long as function takes two arguments, it will be fine. It is a little bit trickier to get the Javascript three argument version, but with a one-liner helper function, it is easy:
def js_enumerate(sequence): for index, obj in enumerate(sequence): yield (index, obj, sequence)
filter(function, js_enumerate(items))
If you want something else, I'm afraid you will have to explain in more detail what you want, sorry.
participants (2)
-
Laurent Lyaudet
-
Steven D'Aprano