重复字符串至特定长度

261 投票
15 回答
319094 浏览
提问于 2025-04-16 02:12

有什么高效的方法可以把一个字符串重复到一定的长度吗?比如说: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:

撰写回答