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