Reputation: 6323
I have a piece of code that will take a string and repeat it such that the length of the string is x.
>>> 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'
Is there any way to optimize it? I need this operation to be fast, as it will be used a lot. Note that this also needs to work with lists.
Upvotes: 1
Views: 1710
Reputation: 1997
If you really want optimizate that you need to rewrite your function in C as an extention for python.
You can find information here. Sorry for my English, I'm new in this.
Upvotes: 0
Reputation: 881745
This might be marginally faster:
def repeat(string, length):
L = len(string)
return string * (length // L) + string[:length % L]
I say "might" because a LOT depends on the typical string
and length
! With 'Hello World'
and 61
, I've timed this (on an old Mac laptop) at 1 microsecond vs 1.66 microseconds for yours; with 'Hello World'*100
and 61*123
, 2.08 microseconds vs 2.68 for yours. Just how fast are you requiring, on what length strings, and for what typical values of length
?
Note //
is "divide by truncation" (just to ensure this works in Python 3 as well as Python 2;-) even though Stack Overflow is coloring things as if it was a comment mark (as in C++).
Upvotes: 3
Reputation: 229633
Instead of int(math.ceil(float(length) / len(data)))
you could just use length/len(data) + 1
. That's not exactly the same but should work as well.
And before trying to make this faster, are you sure that this function is a performance bottleneck? How many thousands of times will you call it each second?
To find out which variant of a function is the fastest one you should profile it, the timeit
module is usually useful there.
Upvotes: 0
Reputation: 89454
There is no need to do floating point here; in old Python versions, just say "int(length) / len(string)", and in new versions you can use the "//" operator. When you get the result, you can just add 1 to make sure it's long enough. Or, at the cost of a few more additions, you can be more precise and never make the initial string too long:
...
return (data * ((int(length) + len(data) - 1) / len(data)))[:length]
Upvotes: 0