重复字符串到一定长度

时间:2010-08-02 19:26:44

标签: string python repeat

将字符串重复到一定长度的有效方法是什么?例如: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

有更好的(更加pythonic)方式吗?也许使用列表理解?

14 个答案:

答案 0 :(得分:595)

Jason Scheirer的回答是正确的,但可以使用更多的说明。

首先,要重复一个字符串整数次,可以使用重载乘法:

>>> 'abc' * 7
'abcabcabcabcabcabcabc'

因此,要重复一个字符串,直到它至少,只要你想要的长度,你计算适当的重复次数并将其放在该乘法运算符的右侧: / p>

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's answer中所建议的那样,可能没有人向下滚动到足以让人注意的程度,你可以使用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%的字节码指令开始。

注意:这些示例使用new-ish //运算符来截断整数除法。这通常被称为 Python 3功能,但根据PEP 238,它在Python 2.2中一直被引入。您只有 才能在Python 3中使用它(或者在具有from __future__ import division的模块中),但可以使用它。

答案 1 :(得分:60)

def repeat_to_length(string_to_expand, length):
   return (string_to_expand * ((length/len(string_to_expand))+1))[:length]

对于python3:

def repeat_to_length(string_to_expand, length):
    return (string_to_expand * (int(length/len(string_to_expand))+1))[:length]

答案 2 :(得分:53)

这是非常pythonic:

newstring = 'abc'*5
print newstring[0:6]

答案 3 :(得分:32)

def rep(s, m):
    a, b = divmod(m, len(s))
    return s * a + s[:b]

答案 4 :(得分:14)

from itertools import cycle, islice
def srepeat(string, n):
   return ''.join(islice(cycle(string), n))

答案 5 :(得分:6)

string * (length / len(string)) + string[0:(length % len(string))]

怎么样?

答案 6 :(得分:6)

也许不是最有效的解决方案,但肯定是短暂的&amp;简单:

def repstr(string, length):
    return (string * length)[0:length]

repstr("foobar", 14)

给予“foobarfoobarfo”。关于这个版本的一件事是如果长度&lt; len(字符串)然后输出字符串将被截断。例如:

repstr("foobar", 3)

给予“foo”。

编辑:实际上令我惊讶的是,这比当前接受的解决方案('repeat_to_length'函数)要快,至少在短字符串上是这样的:

from timeit import Timer
t1 = Timer("repstr('foofoo', 30)", 'from __main__ import repstr')
t2 = Timer("repeat_to_length('foofoo', 30)", 'from __main__ import repeat_to_length')
t1.timeit()  # gives ~0.35 secs
t2.timeit()  # gives ~0.43 secs

据推测,如果弦长,或者长度非常高(也就是说,如果string * length部分的浪费很高)那么它的表现就会很差。事实上,我们可以修改上述内容来验证这一点:

from timeit import Timer
t1 = Timer("repstr('foofoo' * 10, 3000)", 'from __main__ import repstr')
t2 = Timer("repeat_to_length('foofoo' * 10, 3000)", 'from __main__ import repeat_to_length')
t1.timeit()  # gives ~18.85 secs
t2.timeit()  # gives ~1.13 secs

答案 7 :(得分:6)

我用这个:

def extend_string(s, l):
    return (s*l)[:l]

答案 8 :(得分:5)

并不是说这个问题没有足够的答案,而是有重复的功能;只需要列出一个列表然后加入输出:

from itertools import repeat

def rep(s,n):
  ''.join(list(repeat(s,n))

答案 9 :(得分:3)

Yay recursion!

def trunc(s,l):
    if l > 0:
        return s[:l] + trunc(s, l - len(s))
    return ''

不会永远缩放,但对于较小的字符串来说这很好。它很漂亮。

我承认我刚读过Little Schemer,我现在喜欢递归。

答案 10 :(得分:1)

这是使用列表理解的一种方法,尽管随着rpt字符串的长度增加而越来越浪费。

def repeat(rpt, length):
    return ''.join([rpt for x in range(0, (len(rpt) % length))])[:length]

答案 11 :(得分:0)

另一个FP方法:

def repeat_string(string_to_repeat, repetitions):
    return ''.join([ string_to_repeat for n in range(repetitions)])

答案 12 :(得分:0)

c = s.count('a')    
div=n//len(s)    
if n%len(s)==0:
    c= c*div
else:
    m = n%len(s)
    c = c*div+s[:m].count('a')
print(c)

答案 13 :(得分:-2)

def extended_string (word, length) :

    extra_long_word = word * (length//len(word) + 1)
    required_string = extra_long_word[:length]
    return required_string

print(extended_string("abc", 7))