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-the-rest-over-a-python-list > > 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-indices 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. -- Steve
participants (2)
-
Laurent Lyaudet
-
Steven D'Aprano