Feature request enumerate_with_rest or enumerate with skip or filter callback

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

On Sat, Oct 02, 2021 at 12:45:33PM +0200, Laurent Lyaudet wrote:
So if you called it on the list ['a', 'b', 'c', 'd'] it would yield: 0, 'a', ['b', 'c', 'd'] 1, 'b', ['a', 'c', 'd'] 2, 'c', ['a', 'b', 'd'] 3, 'd', ['a', 'b', 'c'] Is that correct? When would you use this? It seems very specialised. The only algorithm I've seen that uses something similar is generating permutations and combinations.
Do you have reason to think that implementing this is C would be significantly faster than doing it in Python? I don't think the overhead of doing it in Python will be much, compared to the cost of iteration and slicing. Nearly all the work is already done in C: the slicing and adding of lists. You might be able to make things a bit faster like this: def enumerate_with_rest(my_list): for i, item in enumerate(my_list): a = [None]*(len(my_list) - 1) a[:i] = my_list[:i] a[i:] = mylist[i + 1:] yield i, item, a but I haven't tested it, it could be slower too. Even if it would be a little faster in C, I'm afraid it is not the responsibility of the stdlib to have an accelerated, optimized implementation of every single obscure and specialised function just because one or two people have a use for it. But if there are lots of uses for this, that might be a different story. -- Steve

Laurent Lyaudet writes:
First, the name confused me, at least: in many contexts dealing with iteration, "rest" means tail. Second, what's wrong with: for i, item in enumerate(my_list): rest = my_list[:i] + my_list[i + 1:] # do stuff with i, item, rest compared to for i, item, rest in enumerate_with_rest(my_list): # do stuff with i, item, rest You save one line, but you (and everyone who reads your code) needs to learn a new function definition, and you need to remember it on every invocation. On the other hand, "explicit is better than implicit" (which goes back to my confusion of "rest" with "tail"). Unless you can show both a substantial speedup with a native C implementation (which leaves out any Python implementation in a different language) and a need for that speed, I'm -1 on defining this at all. It's not one of those cases where defining even a one-line function is easy to get semantically wrong.

Le dim. 3 oct. 2021 à 06:01, Stephen J. Turnbull <stephenjturnbull@gmail.com> a écrit :
Hello, Thanks for your feedback. You do not quote my second email where I also said that enumerate_with_rest was probably too specific and not worth it. I would appreciate your feedback on my second email where I stress out that python is missing a "filter_by_index" construct and give several propositions. Best regards, Laurent Lyaudet

On Sat, Oct 02, 2021 at 12:45:33PM +0200, Laurent Lyaudet wrote:
So if you called it on the list ['a', 'b', 'c', 'd'] it would yield: 0, 'a', ['b', 'c', 'd'] 1, 'b', ['a', 'c', 'd'] 2, 'c', ['a', 'b', 'd'] 3, 'd', ['a', 'b', 'c'] Is that correct? When would you use this? It seems very specialised. The only algorithm I've seen that uses something similar is generating permutations and combinations.
Do you have reason to think that implementing this is C would be significantly faster than doing it in Python? I don't think the overhead of doing it in Python will be much, compared to the cost of iteration and slicing. Nearly all the work is already done in C: the slicing and adding of lists. You might be able to make things a bit faster like this: def enumerate_with_rest(my_list): for i, item in enumerate(my_list): a = [None]*(len(my_list) - 1) a[:i] = my_list[:i] a[i:] = mylist[i + 1:] yield i, item, a but I haven't tested it, it could be slower too. Even if it would be a little faster in C, I'm afraid it is not the responsibility of the stdlib to have an accelerated, optimized implementation of every single obscure and specialised function just because one or two people have a use for it. But if there are lots of uses for this, that might be a different story. -- Steve

Laurent Lyaudet writes:
First, the name confused me, at least: in many contexts dealing with iteration, "rest" means tail. Second, what's wrong with: for i, item in enumerate(my_list): rest = my_list[:i] + my_list[i + 1:] # do stuff with i, item, rest compared to for i, item, rest in enumerate_with_rest(my_list): # do stuff with i, item, rest You save one line, but you (and everyone who reads your code) needs to learn a new function definition, and you need to remember it on every invocation. On the other hand, "explicit is better than implicit" (which goes back to my confusion of "rest" with "tail"). Unless you can show both a substantial speedup with a native C implementation (which leaves out any Python implementation in a different language) and a need for that speed, I'm -1 on defining this at all. It's not one of those cases where defining even a one-line function is easy to get semantically wrong.

Le dim. 3 oct. 2021 à 06:01, Stephen J. Turnbull <stephenjturnbull@gmail.com> a écrit :
Hello, Thanks for your feedback. You do not quote my second email where I also said that enumerate_with_rest was probably too specific and not worth it. I would appreciate your feedback on my second email where I stress out that python is missing a "filter_by_index" construct and give several propositions. Best regards, Laurent Lyaudet
participants (3)
-
Laurent Lyaudet
-
Stephen J. Turnbull
-
Steven D'Aprano