我有一个字符串,其中一个字符('@')需要被“按顺序”和“定期”的一个或多个字符列表中的字符替换。 所以例如我有
'ab@cde@@fghi@jk@lmno@@@p@qrs@tuvwxy@z'
并希望
'ab1cde23fghi1jk2lmno312p3qrs1tuvwxy2z'
代表replace_chars = ['1', '2', '3']
问题在于,在这个例子中,字符串中有更多的@ 比我有替换者。
这是我的尝试:
result = ''
replace_chars = ['1', '2', '3']
string = 'ab@cde@@fghi@jk@lmno@@@p@qrs@tuvwxy@z'
i = 0
for char in string:
if char == '@':
result += replace_chars[i]
i += 1
else:
result += char
print(result)
但这仅在原始字符串中的@不超过3时才有效,否则我会得到 IndexError 。
编辑:感谢您的回答!
答案 0 :(得分:10)
您的代码可以通过添加行if
作为i
子句的最后一行来修复。通过这种方式,您将从>>> from itertools import cycle
>>> s = 'ab@cde@@fghi@jk@lmno@@@p@qrs@tuvwxy@z'
>>> replace_chars = ['1', '2', '3']
>>>
>>> replacer = cycle(replace_chars)
>>> ''.join([next(replacer) if c == '@' else c for c in s])
'ab1cde23fghi1jk2lmno312p3qrs1tuvwxy2z'
除以剩余替换字符列表的长度。
较短的解决方案是使用定期吐出替换字符的生成器。
c
对于字符串s
中的每个字符replacer
,如果字符为'@'
,我们会从$total = 0;
$result = $conn->query("SELECT count(points) as total FROM scores WHERE player_id='$player' ORDER by points ASC");
$row = $result->fetch_array();
if($row['total'] >= 10)
{
$result = $conn->query("SELECT sum(points) as SumPoints FROM scores WHERE player_id='$player' ORDER by points ASC LIMIT 5");
$row = $result->fetch_array();
$total = $row['SumPoints'];
}
生成器获取下一个替换字符,否则它只会给您原来的角色。
为了解释为什么我使用列表推导而不是生成器表达式,请阅读this。
答案 1 :(得分:6)
发电机很有趣。
globals [listOfInitialVals]
turtles-own [val]
to init-turtle
set val random-float 1 ;just for illustration
set listOfTurtleVals (lput val listOfInitialVals)
end
正如PM 2Ring建议的那样,这在功能上与def gen():
replace_chars = ['1', '2', '3']
while True:
for rc in replace_chars:
yield rc
with gen() as g:
s = 'ab@cde@@fghi@jk@lmno@@@p@qrs@tuvwxy@z'
s = ''.join(next(g) if c == '@' else c for c in s)
相同。区别在于itertools.cycle
将在内存中保存一份额外的副本,这可能没有必要。
itertools.cycle
来源:
itertools.cycle
答案 2 :(得分:1)
使用模数后,您还可以保留索引逻辑,使用itertools.count
使用列表组合来跟踪您的位置:
from itertools import count
cn, ln = count(), len(replace_chars)
print("".join([replace_chars[next(cn) % ln] if c == "@" else c for c in string]))
ab1cde23fghi1jk2lmno312p3qrs1tuvwxy2z
答案 3 :(得分:0)
我认为最好不要逐个字符地进行迭代,尤其是对于没有@
的冗长部分的长字符串。
from itertools import cycle, chain
s = 'ab@cde@@fghi@jk@lmno@@@p@qrs@tuvwxy@z'
replace_chars = ['1', '2', '3']
result = ''.join(chain.from_iterable(zip(s.split('@'), cycle(replace_chars))))[:-1]
我不知道如何有效杀死最后一个字符[:-1]
。