2010-08-02 77 views
130

什麼是將字符串重複到一定長度的有效方法?例如: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)的方式來做到這一點?也許使用列表理解?

回答

37
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] 
+5

看起來這是利用整數師。在Python 3中,這不需要'//'嗎?或者刪除'+ 1'並使用明確的呼叫到天花板功能就足夠了。另外,請注意:生成的字符串實際上在均勻分割時會有額外的重複;多餘的部分被拼接切斷。起初讓我困惑。 – jpmc26 2013-05-03 22:49:20

+0

'int()'在這裏做同樣的事情,但是,'// //'可能在微觀上更快,因爲它在一個命令而不是兩個命令中執行了分隔和底線。 – Doyousketch2 2018-01-15 14:35:08

489

重複字符串的固定次數是一個內置的操作:

'abc' * 7 

所以,只要計算出你需要重複的次數達到你想要的長度,並把它放在RHS上。然後你需要修剪到合適的長度。

(看來,這是對方的回答做什麼,但一點點的解釋似乎是有用的。)

+7

這應該是被接受的答案。 – 2016-09-12 19:33:43

+8

不,OP要的結果是長度爲7(這不是3的倍數)。 – IanS 2017-03-02 14:24:49

+0

此功能的名稱是什麼?重複的concat? – 2017-04-16 04:44:35

4

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

+0

'length/len(string)'需要在括號中包裝,並且你錯過了最後一個']'。 – MikeWyatt 2010-08-02 19:36:10

+1

在我看來,迄今爲止最具可讀性/直觀性。我認爲你需要在Python 3中使用'//'進行整數除法。拼接中的'0'是可選的。 (當然,冒號是必需的。) – jpmc26 2013-05-03 22:48:27

1

這是使用列表理解來做到這一點的一種方式,雖然隨着rpt字符串的長度增加,它越來越浪費。

def repeat(rpt, length): 
    return ''.join([rpt for x in range(0, (len(rpt) % length))])[:length] 
13
from itertools import cycle, islice 
def srepeat(string, n): 
    return ''.join(islice(cycle(string), n)) 
29
def rep(s, m): 
    a, b = divmod(m, len(s)) 
    return s * a + s[:b] 
+1

絕對是目前爲止最好看的。 +1 – Triptych 2010-08-06 16:24:05

+0

它可以在包含數值的字符串上正常工作+1 – Ropstah 2015-03-08 13:16:53

+2

這應該是公認的答案。 – Nimrod 2016-09-20 22:15:10

3

耶遞歸!

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

不會永遠縮放,但對較小的字符串可以。而且很漂亮。

我承認我只是讀了Little Schemer,現在我喜歡遞歸。

3

也許不是最有效的解決方案,但可以肯定的短&簡單:

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

repstr("foobar", 14) 

給出 「foobarfoobarfo」。有關這個版本的一點是,如果長度爲< len(string),那麼輸出字符串將被截斷。例如:

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 
+1

您可以根據輸入和輸出長度在兩個版本之間添加一個開關,以實現最佳優化。 – 2016-06-20 21:37:24

0

另一個FP的形式給出:

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

不是說有沒有足夠的這個問題的答案,但有一個復讀功能;只需要製作一個列表,然後加入輸出:

from itertools import repeat 

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

我用這個:

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

這是非常Python化:

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

'0:7'如果你想要OP這樣的7個字符。 – 2016-06-20 21:35:25

+0

這應該被標記爲正確的答案。 – marverix 2018-02-10 08:44:33