2017-04-17 66 views
2

我想了解replace方法。我有一串數字,我想進行一些調整。具體地講,我會歸類基於閾值的數字:如何正確循環並替換字符串中的元素?

def makeAdjustment(x): 
    for each in x: 
     if int(each) < 5: 
      x = x.replace(each, "0") 
     else: 
      x = x.replace(each, "1") 
    return x 

在使用中:

>>> makeAdjustment("800857237867") == "100111001111" 
True 
>>> makeAdjustment("15889923") == "01111100" 
True 
>>> makeAdjustment("14963896") == "00110111" 
True 

然而,如果數字序列變得更大的字符串被轉換成零:

>>> makeAdjustment("366058562030849490134388085")  
'000000000000000000000000000' 
+3

想一想 - 在將所有數字替換爲5以上的所有數字之後,**所有數字都低於5 **。 – jonrsharpe

+0

'replace'方法返回字符串的一個副本,其中所有出現的舊字符串都被new替換。所以,最終一切都變成零。 – Charul

+1

每個數字都是對的?替換替換所有的數字,而不僅僅是該位置的數字。你想要它的位置? – jwillis0720

回答

3

這裏的問題不是字符串較大,而是'1''0'的實例不應該被替換。當您在字符串中稍後遇到'1'(與您上一次的情況相同)時,您會將'1'的所有先前實例替換爲'0'

一種解決方案是特殊情況,他們說:

def makeAdjustment(x): 
    for each in x: 
     if int(each) in {'1', '0'}: 
      continue 
     if int(each) < 5: 
      x = x.replace(each, "0", 1) 
     else: 
      x = x.replace(each, "1") 
    return x 

這是一個選擇,但既然你打電話replace每次迭代這是不是最好的。你可以只用join這裏做的更好:

def makeAdjustment(x): 
    return "".join("1" if int(i) > 5 else "0" for i in x) 

這是更清潔,更清晰,速度快:

# for loop 
%timeit makeAdjustment("366058562030849490343880185") 
10000 loops, best of 3: 39.1 µs per loop 
# join 
%timeit makeAdjustment("366058562030849490343880185") 
100000 loops, best of 3: 17.7 µs per loop 
2

如果您要更換的每個字符,建立由字符一個新的字符串的字符,而不是使用replace

def makeAdjustment(x): 
    result = [] 
    for each in x: 
     if int(each) < 5: 
      result.append("0") 
     else: 
      result.append("1") 
    return ''.join(result) 

或簡稱:

def makeAdjustment(x): 
    return ''.join("0" if int(each) < 5 else "1" for each in x) 
1

我這樣做的方法只是把它變成一個列表並按位置走。它是如此容易得多,因爲替換被替換所有的每個字符無論身在何處的位置這裏我們使用的每個作爲一個指標來跟蹤我們的位置在列表

def makeAdjustment(x): 
    x = list(x) 
    for each in range(len(x)+1): 
     if int(x[each]) < 5: 
      x[each] = '0' 
     else: 
      x[each] = '1' 
     #Turn it back into a string instead of a list 
     x = "".join(x) 
     return x 
1
def makeAdjustment(x): 
    splitted = [c for c in enumerate(x)] 
    for each in splitted: 
     if int(each[1]) < 5: 
      splitted[each[0]] = "0" 
     else: 
      splitted[each[0]] = "1" 

    return "".join(splitted) 

編輯:上面的代碼分裂該字符串並生成一個元組列表,其中字符串中的每個字符都伴隨着它的索引。這是通過使用enumerate完成的。

列表(splitted)被枚舉,其中each[1]將包含字符串中的實際字符,而each[0]將包含給定字符串中實際字符的索引。

根據each[1]中包含的值,修改了拆分索引each[0]中包含的值。

最後,字符串使用"".join(splitted)加入。

+0

你可能會添加幾句話來解釋你的解決方案嗎?對許多人來說,只是查看代碼是沒有幫助的。 –

+1

@JimFasarakisHilliard:我已經添加了解釋。不感到pythonic,但完成工作。 – shahkalpesh