Как эффективно переместить кортеж влево? - PullRequest
2 голосов
/ 14 марта 2011

Я ищу эффективный способ сдвинуть кортеж влево.

То, что я сделал до сих пор:

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

Количество мест для сдвига задано каквторой аргумент.

Это эффективно?Может ли он быть закодирован более Pythonic?

И скажите мне, это ...

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

более эффективно, чем

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

?

Я имею в виду, len(tup) O (1) или я должен помнить это для дальнейшего использования?

Ответы [ 2 ]

9 голосов
/ 14 марта 2011

То, что вы делаете, - это абсолютная микрооптимизация, которая является пустой тратой времени, если вы точно не знаете, к чему стремитесь.

Первая версия вашего кода, вероятно, быстрее, потому что она использует на один вызов меньше функции, но оба в порядке. Если вы действительно заботитесь о скорости, вы должны сначала выяснить, как использовать профилировщик и модуль 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))

случайное время, результаты

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

Итак:

  • Самый питоновский код (try .. except и if tup:) - самый быстрый. Должен любить Python за это.
  • Вы можете сэкономить невероятное количество 0,0000001 секунд.
6 голосов
/ 14 марта 2011

Чуть более кратко

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