2017-04-17 163 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