>>> x=('a', 'b', 'c', 'd')
>>> [x[i] for i in range(len(x)) if i != 2]
['a', 'b', 'd']
I have the above tuple with 4 elements. I want to generate an array with the 3rd element in the tuple removed.
Is this the most succinct and efficient way to express this operation?
CodePudding user response:
You could use slice notation to do so.
>>> x = ("a", "b", "c", "d")
>>> result = list(x[:2] x[3:])
>>> print(result)
['a', 'b', 'd']
At such a small scale, the difference in performance would be insignificant, but if we really want to measure it.
import timeit
stmt_range = """
x = ("a", "b", "c", "d")
result = [x[i] for i in range(len(x)) if i != 2]
"""
stmt_slice = """
x = ("a", "b", "c", "d")
result = list(x[:2] x[3:])
"""
print(min(timeit.Timer(stmt=stmt_range).repeat(7, 100000)))
print(min(timeit.Timer(stmt=stmt_slice).repeat(7, 100000)))
Outputs
0.041514699998515425
0.0190705999993952
So the use of slice notation would be slightly faster.
CodePudding user response:
Convert the tuple to a list and then use the pop method. This avoids iteration and you can even make it a function.
def remove(tup, idx):
l = list(tup)
l.pop(idx)
return l
This is my first time using the timeit module, but here is what I got.
import timeit
x = tuple([i for i in range(10000)])
def myfunc (tup, idx):
l = list(tup)
l.pop(idx)
return l
def shadow(tup, idx):
l = list(tup)
del l[idx]
return l
print("juanpa.arrivillaga")
print(timeit.timeit("[e for i,e in enumerate(x) if i != 2]", setup = "from __main__ import x", number=10000))
print("Antoine Delia")
print(timeit.timeit("list(x[:2] x[3:])", setup = "from __main__ import x", number=10000))
print("My solution")
print(timeit.timeit(stmt="myfunc(x,2)", setup = "from __main__ import myfunc, x", number=10000))
print("ShadowRanger")
print(timeit.timeit(stmt="shadow(x,2)", setup = "from __main__ import shadow, x", number=10000))
Output:
juanpa.arrivillaga
9.834354800000256
Antoine Delia
2.695629099999678
My solution
0.6217948999997134
ShadowRanger
0.6193107999997665