我正在寻找一种更Python化的方法,用列表中的值替换字符串中已知长度的占位符。它们应按顺序更换,并且只能使用一次。例如,使用以下值:
switch boysAge {
case ...20:
message += "underage"
case 21..<70 :
message += "allowed"
default:
break
}
我希望得到:
replaceVals = ['foo', 'bar']
origStr = 'I went to the ? to get ?'
我可以通过以下循环获得所需的结果,但是我觉得应该有比使用这样的循环更好的方法。
newStr = 'I went to the foo to get bar'
答案 0 :(得分:2)
这是使用发电机的想法:
replaceVals = iter(['foo', 'bar'])
origStr = 'I went to the ? to get ?'
(' ').join(next(replaceVals) if i == '?' else i for i in origStr.split())
输出:
'I went to the foo to get bar'
这样做的好处是replaceVals
中的项目数量不必与origStr
中要替换的项目数量相匹配:
replaceVals = iter(['foo', 'bar', 'other'])
origStr = 'I went to the ? to get ?'
(' ').join(next(replaceVals) if i == '?' else i for i in origStr.split())
#'I went to the foo to get bar'
但是在这种情况下使用字符串格式会导致错误。
答案 1 :(得分:2)
您可以使用字符串的replace
和format
方法,如下所示:
origStr.replace('?','{}').format(*replaceVals)
Out[334]: 'I went to the foo to get bar'
答案 2 :(得分:1)
@roganjosh的注释中的答案是可能是最好的,虽然OP是抽象的,以至于目前还不清楚他的真实情况是什么。我很好奇是否有人可以用Python3中显示的f字符串来做到这一点。使f字符串不如@roganjosh有吸引力的原因在于,通过.format()
调用来轻松地替换替换序列非常容易。就是说, IF 您想尝试一个f字符串,这样的方法将起作用:
replaceVals = ['foo', 'bar']
stream = iter(replaceVals)
f'I went to the {stream.next()} to get {stream.next()}'
答案 3 :(得分:0)
f字符串
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>/nexus-data/log/myApp.log</file>
<encoder>
<pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="FILE" />
</root>
</configuration>
答案 4 :(得分:0)
您可以使用'?'
分割字符串,然后使用itertools.zip_longest
将结果列表中的子字符串与replaceVals
中的替换字符串配对,并以空字符串作为填充值,然后将用生成器表达式展平后的字符串对:
from itertools import zip_longest
''.join(i for p in zip_longest(origStr.split('?'), replaceVals, fillvalue='') for i in p)