How to efficiently left-shift a tuple?
I'm looking for an efficient way to left-shift a tuple.
What I've done so far:
def leftShift(tup, n):
length = len(tup)
if length != 0:
n = n % length
else:
return tuple()
return tup[n:] + tup[0:n]
sample = (1,2,3,4)
sample2 = ()
print(leftShift(sample, 5)) #prints (2, 3, 4, 1)
print(leftShift(sample, 1)) #prints (2, 3, 4, 1)
print(leftShift(sample, 15)) #prints (4, 1, 2, 3)
print(leftShift(sample, 3)) #prints (4, 1, 2, 3)开发者_StackOverflow社区
print(leftShift(sample2, 4)) #prints ()
The number of places to shift is given as the second argument.
Is it efficient? Can it be coded in more Pythonic way?
And tell me, is it...
length = len(tup)
if length != 0:
n = n % length
more efficient than
if len(tup) != 0:
n = n % len(tup)
?
I mean, is len(tup)
O(1) or should I remember it for later usage?
What you're doing is absolute micro-optimization, which is a total waste of time if you don't know exactly what you're aiming for.
The first version of you code is probably faster because it uses one less function call, but both are fine. If you really care about speed you should figure out how to use a profiler and the timeit module first.
len(tup)
takes constant time.
Maybe you want a deque which has a rotate method?
Here are some alternatives:
def leftShift1(tup, n):
try:
n = n % len(tup)
except ZeroDivisionError:
return tuple()
return tup[n:] + tup[0:n]
def leftShift2(tup, n):
length = len(tup)
if length != 0:
n = n % length
else:
return tuple()
return tup[n:] + tup[0:n]
def leftShift3(tup, n):
if len(tup) != 0:
n = n % len(tup)
else:
return tuple()
return tup[n:] + tup[0:n]
def leftShift4(tup, n):
if tup:
n = n % len(tup)
else:
return tuple()
return tup[n:] + tup[0:n]
sample= tuple(range(10))
random timeit results
D:\downloads>python -m timeit -s"from asd import *" "leftShift1(sample, 20)"
1000000 loops, best of 3: 0.472 usec per loop
D:\downloads>python -m timeit -s"from asd import *" "leftShift2(sample, 20)"
1000000 loops, best of 3: 0.533 usec per loop
D:\downloads>python -m timeit -s"from asd import *" "leftShift3(sample, 20)"
1000000 loops, best of 3: 0.582 usec per loop
D:\downloads>python -m timeit -s"from asd import *" "leftShift4(sample, 20)"
1000000 loops, best of 3: 0.474 usec per loop
So:
- The most Pythonic code (
try .. except
andif tup:
) is the fastest. Gotta love Python for that. - You can save the incredible amount of 0.0000001 seconds.
A little more tersely
def leftShift(tup, n):
if not tup or not n:
return tup
n %= len(tup)
return tup[n:] + tup[:n]
精彩评论