如何高效地左移元组?

2 投票
2 回答
6171 浏览
提问于 2025-04-16 13:39

我在寻找一种高效的方法来左移一个元组。

到目前为止,我做了以下工作:

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)
print(leftShift(sample2, 4)) #prints ()

要左移的位数是作为第二个参数给出的。

这样做效率高吗?有没有更符合Python风格的写法?

另外,能告诉我,这个方法...

length = len(tup)
if length != 0:
    n = n % length

比这个方法更高效吗

if len(tup) != 0:
    n = n % len(tup)

我想问的是,len(tup) 是 O(1) 吗,还是我应该记住这个信息以备后用?

2 个回答

7

稍微简洁一点

def leftShift(tup, n):
    if not tup or not n:
        return tup
    n %= len(tup)
    return tup[n:] + tup[:n]
9

你现在做的事情是非常细微的优化,如果你不知道自己到底想要什么,那这完全是在浪费时间。

你代码的第一个版本可能更快,因为它少调用了一个函数,但其实两个版本都没问题。如果你真的很在意速度,首先应该学习如何使用性能分析工具和timeit模块。

len(tup)这个操作是恒定时间的,也就是说,不管你传入什么,它所需的时间都是一样的。

也许你想要一个双端队列(deque),它有一个旋转的方法?

这里有一些替代方案:

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))

随机的timeit结果

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

所以:

  • 最符合Python风格的代码(try .. exceptif tup:)是最快的。这就是Python的魅力所在。
  • 你可以节省的时间是0.0000001秒,真是微不足道。

撰写回答