重复字符串至特定长度
有什么高效的方法可以把一个字符串重复到一定的长度吗?比如说:repeat('abc', 7) -> 'abcabca'
这是我现在的代码:
def repeat(string, length):
cur, old = 1, string
while len(string) < length:
string += old[cur-1]
cur = (cur+1)%len(old)
return string
有没有更好的(更符合Python风格的)方法来实现这个?也许可以用列表推导式?
15 个回答
72
这段代码写得很符合Python的风格:
newstring = 'abc'*5
print newstring[0:6]
753
Jason Scheirer的回答是正确的,但可以再详细解释一下。
首先,如果你想把一个字符串重复一定次数,可以用重载的乘法来实现:
>>> 'abc' * 7
'abcabcabcabcabcabcabc'
所以,如果你想把一个字符串重复到至少达到你想要的长度,你需要计算出合适的重复次数,然后把它放在乘法运算符的右边:
def repeat_to_at_least_length(s, wanted):
return s * (wanted//len(s) + 1)
>>> repeat_to_at_least_length('abc', 7)
'abcabcabc'
接着,你可以用数组切片来把它修剪到你想要的确切长度:
def repeat_to_length(s, wanted):
return (s * (wanted//len(s) + 1))[:wanted]
>>> repeat_to_length('abc', 7)
'abcabca'
另外,正如pillmod的回答中提到的,可能没有人再往下滚动去注意到,你可以使用divmod
来一次性计算出需要的完整重复次数和额外的字符数:
def pillmod_repeat_to_length(s, wanted):
a, b = divmod(wanted, len(s))
return s * a + s[:b]
那么,哪个更好呢?我们来做个性能测试:
>>> import timeit
>>> timeit.repeat('scheirer_repeat_to_length("abcdefg", 129)', globals=globals())
[0.3964178159367293, 0.32557755894958973, 0.32851039397064596]
>>> timeit.repeat('pillmod_repeat_to_length("abcdefg", 129)', globals=globals())
[0.5276265419088304, 0.46511475392617285, 0.46291469305288047]
结果显示,pillmod的版本大约慢了40%,这有点可惜,因为我个人觉得它更容易理解。造成这种情况的原因有几个,首先是它编译成的字节码指令多了大约40%。
注意:这些例子使用了新的//
运算符来进行整数除法的截断。这通常被称为Python 3的一个特性,但根据PEP 238,它实际上在Python 2.2就已经引入了。你只需要在Python 3中使用它(或者在使用了from __future__ import division
的模块中),但你无论如何都可以使用它。
82
def repeat_to_length(string_to_expand, length):
return (string_to_expand * ((length/len(string_to_expand))+1))[:length]
def repeat_to_length(string_to_expand, length):
return (string_to_expand * (int(length/len(string_to_expand))+1))[:length]
对于python3: