Reputation: 827
I have a list of tuples, from which I am removing the ith element. Right now I'm doing this with:
map(lambda e: list(e)[:i] + list(e)[(i + 1):], data)
which converts the tuple to a list (twice!) and then slices out the element. The result means that I have lists instead of tuples- but this is perfectly fine. Is there a faster way of doing this, possibly by converting each tuple to a list in a separate map operation?
Upvotes: 2
Views: 121
Reputation: 476709
No need to wrap this to a list, you can just:
map(lambda e: (*e[:i], *e[i+1:]), data)
But these approaches all will take O(m n) time with m the arity of the tuples and n the number of tuples.
The above will also process siceable iterables, so not per se tuples. Furthermore the result is always a tuple. For example for a range(..)
object:
>>> i=3
>>> list(map(lambda e: (*e[:i], *e[i+1:]), [range(1,7)]))
[(1, 2, 3, 5, 6)]
This is not per se wanted behavior. One can also use e[:i] + e[i+1:]
, this will then raise an error for a range(..)
object. For a list
, it will return a list
. There is not an "inherent" better approach: it depends on the use case.
Upvotes: 3
Reputation: 1122232
You don't need to convert to a list at all. Just slice the tuple; slicing doesn't mutate a tuple, it creates a new object:
map(lambda e: e[:i] + e[i:], data)
Not that the above slice operations are any use, because slicing to i
and from i
would create the exact same tuple. You want to add 1 to the start of the second slice if i
should be omitted:
map(lambda e: e[:i] + e[i + 1:], data)
Demo:
>>> t = (41, 42, 45, 54, 81, 162)
>>> t[:3] + t[3:] # same tuple again
(41, 42, 45, 54, 81, 162)
>>> t[:3] + t[4:] # skip index 3
(41, 42, 45, 81, 162)
You may want to reconsider using tuples here; tuples are really more designed for heterogenous data structures; tuples have structure, lists have order. See What's the difference between lists and tuples?
Upvotes: 6