2010-06-20 2 views
1

У меня есть часть кода, которая возьмет строку и повторит ее так, что длина строки равна x.Оптимизация: Повторение строки Python

>>> import math 
>>> def repeat(data, length): 
     return (data * int(math.ceil(float(length)/len(data))))[:length] 
>>> repeat("Hello World", 22) 
'Hello WorldHello World' 
>>> repeat("Hello World", 20) 
'Hello WorldHello Wor' 

Есть ли способ его оптимизации? Мне нужна эта операция, чтобы быть быстрой, так как она будет использоваться много. Обратите внимание, что это также необходимо для работы со списками.

+0

Просто интересно. Вы действительно подтвердили, что 'repeat (« Hello World », 22)' быстрее, чем «Hello World» * 22' – Wolph

+0

@WoLpH: Он решает немного другую проблему. Он хочет, чтобы «Hello World» (или любая строка) повторялся столько раз, сколько необходимо, но не превышал N символов в длину. Не то же самое, что 'string * n'. –

+0

@Brian: действительно, в этом случае мой вопрос недействителен :) Я не вижу возможности оптимизировать это гораздо дальше. Простого сравнения должно быть достаточно. – Wolph

ответ

3

Это может быть немного быстрее:

def repeat(string, length): 
    L = len(string) 
    return string * (length // L) + string[:length % L] 

Я говорю «может», потому что многое зависит от типичного string и length! С 'Hello World' и 61 я приурочил это (на старом ноутбуке Mac) до 1 микросекунды против 1,66 микросекунды для вас; с 'Hello World'*100 и 61*123, 2.08 микросекунд против 2.68 для вашего. Просто как быстро вы требуете, на каких длинах строк и для каких типичных значений length?

Примечание: // является «делением на усечение» (только для обеспечения того, что это работает в Python 3, а также Python 2 ;-), хотя Stack Overflow окрашивает вещи так, как если бы это была метка комментария (как на C++).

+0

Это немного ускоряет его, оно должно быть достаточно хорошим. Благодаря! – skeggse

+0

@CMC, добро пожаловать! –

0

Здесь нет необходимости делать с плавающей запятой; в старых версиях Python просто скажите «int (length)/len (string)», а в новых версиях вы можете использовать оператор «//». Когда вы получите результат, вы можете просто добавить 1, чтобы убедиться, что это достаточно долго. Или, по стоимости несколько больше дополнений, вы можете быть более точным и никогда не делают начальная строка слишком долго:

... 
    return (data * ((int(length) + len(data) - 1)/len(data)))[:length] 
0

Вместо int(math.ceil(float(length)/len(data))) вы могли бы просто использовать length/len(data) + 1. Это не совсем то же самое, но должно работать.

И прежде чем пытаться сделать это быстрее, вы уверены, что эта функция является узким местом производительности? Сколько тысяч раз вы будете называть его каждую секунду?

Чтобы узнать, какой вариант функции является самым быстрым, вы должны его профиль, модуль timeit обычно полезен там.

0

Если вы действительно хотите оптимизировать, что вам нужно переписать свою функцию в C как расширение для python.

here. Извините за мой английский, я новичок в этом.

+0

Мне нужно сохранить его на python, хотя «Python» и «speed» не очень хорошо сочетаются. – skeggse

Смежные вопросы