我的Python代码涉及替换功能有问题

时间:2017-06-14 19:21:46

标签: python

我正在创建一个关于用多个数字替换字符串的多个部分的函数,但由于某种原因,输出不是我所期望的。

from pyprimes import isprime
def prime_replace(x, l = []):
    lst = []
    string = str(x)
    for n in range(10):
        for i in l:
            string = string.replace(string[i], str(n))
        lst.append(int(string))
    return lst 

print prime_replace(x = 56243, l = [2, 3])

这个函数的输出是一个列表[56003,56113,56223,56333,56444,56555,56666,77777,88888,99999],但我想要的是[56003,56113,56223,56333,56443,565553, 56663,56773,56883,56993]有人可以帮助我并告诉我出了什么问题,谢谢。

4 个答案:

答案 0 :(得分:3)

您正在修改原始字符串,replace正在替换“所有出现次数”

以下是打印输出的一部分,了解它如何生成您看到的输出:

...
string is now 56333
replacing 3 with 3
string is now 56333
replacing 3 with 4
string is now 56444
...

您可以看到我们已成功获得56333,但您希望将str[2](实际值:3)替换为str(n)(实际值: 4),取代了{em>所有次出现的3

此特定方案的一种解决方法是复制字符串:

def prime_replace(x, l = []):
    lst = []
    string = str(x)
    for n in range(10):
        newstr = string
        for i in l:
            newstr = newstr.replace(string[i], str(n))
        lst.append(int(newstr))
    return lst 

print prime_replace(x = 56243, l = [2, 3])

输出:

[56003, 56113, 56223, 56333, 56443, 56553, 56663, 56773, 56883, 56993]

Demo (not recommended)

但是,replace可能不是最好的选择,因为它会用“newstring”替换所有出现的“oldstring”。看起来您真正要做的就是将string中的索引更改为l,使其成为range(10)中的下一个值,我们可以通过索引和追加来实现:

def prime_replace(x, l = []):
    lst = []
    string = str(x)
    for n in range(10):
        newstr = string
        for i in l:
            newstr = newstr[0:i]+str(n)+newstr[i+1:];
        lst.append(int(newstr))
    return lst 

Demo (better)

答案 1 :(得分:0)

string.replace(a,b)替换a的所有实例。因此,' 56243' .replace(3,0)评估为' 56240'。您正在尝试替换l中的标记处的值,因此您应该替换

string = string.replace(string[i], str(n))

string = string[:i] + str(n) + string[i+1:]

如果要替换的索引的值在数字的其他地方重复,即prime_replace(562432,[2,3])

,则另一个答案失败

答案 2 :(得分:0)

我还通过将字符串转换为列表

找到了另一种解决方案
from pyprimes import isprime
def prime_replace(x, l):
    lst = []
    string_lst = list(str(x))
    for n in range(10):
        for i in l:
            string_lst[i] = str(n)
        lst.append(int("".join(string_lst)))
    return lst 

print prime_replace(56243, [2, 3])

输出

[56003, 56113, 56223, 56333, 56443, 56553, 56663, 56773, 56883, 56993]

但非常感谢你的解决方案。

答案 3 :(得分:0)

你真的想要一个可变的数据结构来简化你的逻辑。您可以使用bytearray获取本质上可变的字符串。所以这是另一种方法:

In [11]: def prime_replace(x, l=None):
    ...:     if l is None:
    ...:         l = [] # careful with mutable default arguments
    ...:     lst = []
    ...:     string = bytearray(str(x), encoding='ascii')
    ...:     for n in b'0123456789':
    ...:         for i in l:
    ...:             string[i] = n
    ...:         lst.append(int(string))
    ...:     return lst
    ...:

In [12]: prime_replace(x = 56243, l = [2, 3])
Out[12]: [56003, 56113, 56223, 56333, 56443, 56553, 56663, 56773, 56883, 56993]

另外,be careful with mutable default arguments

我使用bytearray,因为我认为它可以简化事情。列表也有效。但请注意bytearray并直接在ascii b'012345679'上进行迭代,它会大大简化所有内容,而且您不必在str和{之间来回转换内容{1}}