我想构建一个程序,用shuflo列表中的每一项替换12345,但是如果shuflo列表包含从1到5的数字,它也会替换它们。
下面是我的代码:shuflo = [1, 2, 3, 4, 5]
def build(x):
random.shuffle(shuflo)
lock = shuflo
lack = str(x)
lack = lack.replace("1", str(lock[0]))
lack = lack.replace("2", str(lock[1]))
lack = lack.replace("3", str(lock[2]))
lack = lack.replace("4", str(lock[3]))
lack = lack.replace("5", str(lock[4]))
Ponf = [lack, eval(lack)]
return Ponf
print(build("(1)+(2)+(3)+(4)+(5)"))
典型的结果是:
['(3)+(1)+(2)+(3)+(5)', 14]
在list shuflo中只有3个元素中的一个,但是有些元素被替换了两次,所以它不起作用。
我怎么能解决这个问题??
每个数字只需替换一次。这可以通过re
模块完成,或者,如果数字只有一个字符长(即从0到9),则可以在遍历字符串的每个字符的列表推导中完成。
使用正则表达式:
import random
import re
def build(x,shuflo=[1, 2, 3, 4, 5]):
shuffled = random.sample(shuflo,len(shuflo))
d = {str(i):str(v) for i,v in zip(shuflo,shuffled)}
pattern = "|".join(sorted(d,key=len,reverse=True))
return re.sub(pattern,lambda c:d[c.group()],x)
build("(1)+(2)+(3)+(4)+(5)")
'(5)+(3)+(2)+(4)+(1)'
使用列表推导式(单个字符替换):
import random
def build(x,shuflo=[1, 2, 3, 4, 5]):
shuffled = random.sample(shuflo,len(shuflo))
d = {str(i):str(v) for i,v in zip(shuflo,shuffled)}
return "".join(d.get(c,c) for c in x)
build("(1)+(2)+(3)+(4)+(5)")
'(1)+(4)+(5)+(2)+(3)'
maketrans也适用于单个字符替换:
def build(x,shuflo=[1, 2, 3, 4, 5]):
shuffled = random.sample(shuflo,len(shuflo))
d = {str(i):str(v) for i,v in zip(shuflo,shuffled)}
return x.translate(str.maketrans(d))
尝试如下:
import random
shuflo = [1, 2, 3, 4, 5]
def build(x):
random.shuffle(shuflo)
lack = str(x)
table = str.maketrans({str(i): str(shuflo[i-1]) for i in range(1,len(shuflo)+1})
lack = lack.translate(table)
Ponf = [lack, eval(lack)]
return Ponf
print(build("(1)+(2)+(3)+(4)+(5)"))
这肯定可以优化很多,但我不确定你的确切用例。