简体   繁体   English

在Python中“定期”替换字符串中字符的最佳方法是什么?

[英]What's the best way to “periodically” replace characters in a string in Python?

I have a string where a character ('@') needs to be replaced by characters from a list of one or more characters "in order" and "periodically". 我有一个字符串,其中一个字符('@')需要被“按顺序”和“定期”的一个或多个字符列表中的字符替换。 So for example I have 所以我举个例子

'ab@cde@@fghi@jk@lmno@@@p@qrs@tuvwxy@z'

and want 并希望

'ab1cde23fghi1jk2lmno312p3qrs1tuvwxy2z'

for replace_chars = ['1', '2', '3'] for replace_chars = ['1', '2', '3']

The problem is that in this example there are more @ in the string than I have replacers. 问题是在这个例子中,字符串中的@比我有替换者的更多。

This is my try: 这是我的尝试:

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)

but this only works of course if there are not more than three @ in the original string and otherwise I get IndexError . 但是这只有在原始字符串中不超过3个@的情况下才有效,否则我会得到IndexError

Edit: Thanks for the answers! 编辑:谢谢你的回答!

Your code could be fixed by adding the line i = i%len(replace_chars) as the last line of your if clause. 您的代码可以通过添加行i = i%len(replace_chars)作为if子句的最后一行来修复。 This way you will be taking the remainder from the division of i by the length of your list of replacement characters. 通过这种方式,您将从i的除法中取出剩余的替换字符列表的长度。

The shorter solution is to use a generator that periodically spits out replacement characters. 较短的解决方案是使用定期吐出替换字符的生成器。

>>> 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'

For each character c in your string s , we get the next replacement character from the replacer generator if the character is an '@' , otherwise it just gives you the original character. 对于字符串s每个字符c ,如果字符为'@' ,我们将从replacer生成器中获取下一个替换字符,否则它只会为您提供原始字符。

For an explanation why I used a list comprehension instead of a generator expression, read this . 为了解释为什么我使用列表推导而不是生成器表达式,请阅读此内容

Generators are fun. 发电机很有趣。

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)

As PM 2Ring suggested, this is functionally the same as itertools.cycle . 正如PM 2Ring所建议的那样,这在功能上与itertools.cycle相同。 The difference is that itertools.cycle will hold an extra copy of the list in memory which may not be necessary. 区别在于itertools.cycle将在内存中保存一个额外的列表副本,这可能不是必需的。

itertools.cycle source: itertools.cycle源码:

def cycle(iterable):
    saved = []
    for element in iterable:
        yield element
        saved.append(element)
    while saved:
        for element in saved:
              yield element

You could also keep your index logic once you use modulo, using a list comp by using itertools.count to keep track of where you are: 一旦使用模数,您也可以保留索引逻辑,使用列表comp通过使用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

I think it is better to not iterate character-by-character, especially for long string with lengthy parts without @ . 我认为最好不要逐个字符地迭代,特别是对于没有@冗长部分的长字符串。

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]

I don't know how to efficiently kill last char [:-1] . 我不知道如何有效地杀死最后一个char [:-1]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 替换字符串中多个字符的最佳方法? - Best way to replace multiple characters in a string? 用A + B列中的字符替换[C]中的字符的最佳方法是什么 - What's the best way to replace a character in [C] with characters from column A+B 在python中挑选特定模式的字符串的最佳方法是什么? - What‘s the best way to pick out string of a specific pattern in python? 什么是在python中确定unicode字符串的解码方法的最佳方法 - What's the best way to determine decoding method of a unicode string in python 用Python替换大字符串中字符的最佳方法? - Optimal way to replace characters in large string with Python? 从字符串中递归删除最终字符 - 这是最好的方法吗? - Remove final characters from string recursively - What's the best way to do this? 用Python基础拉丁语替换国际字符的好方法是什么? - What's a good way to replace international characters with their base Latin counterparts using Python? 使用Python剥离和替换高unicode字符文档的最快方法是什么? - What's the fastest way to strip and replace a document of high unicode characters using Python? 在 Python 中,除了使用 str.translate() 之外,替换给定字符串中某些字符的最快方法是什么? - In Python, what is the fastest way to replace certain characters in a given string other than using str.translate()? 在python中的字符串中替换2个字符 - Replace 2 characters in a string in python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM