如何以高效的方式使用列表中的元素替换字符串的特定字符?

huangapple go评论68阅读模式
英文:

How to replace particular characters of a string with the elements of a list in an efficient way?

问题

代码中的主要目标是将输入字符串 input_str 中的@字符替换为idx_list 中的相应元素。您已经编写了一个有效的函数来完成这个任务,但您是否想要更短和更快的方法。

以下是一个使用列表解析的简短和更紧凑的方法:

def replace_char(input_str, idx_list):
    output_str = ''.join(str(idx) if char == '@' else char for char, idx in zip(input_str, idx_list))
    return output_str

这个函数使用 zip 函数将 input_stridx_list 遍历在一起,然后根据 @ 字符是否出现来选择替换或保留原始字符,最后使用 join 方法将它们连接成一个字符串。

这种方法可能会更快,因为它避免了在每次迭代时进行字符串连接。

英文:

There is a string:

input_str = 'The substring of "python" from index @ to index @ inclusive is "tho"'

and a list of indices:

idx_list = [2, 4]

I want to replace the character @ in str_input with each element of the idx_list to have the following output:

output_str = 'The substring of "python" from index 2 to index 4 inclusive is "tho"'

So I have coded it as follows:

def replace_char(input_str, idx_list):
    output_str = ""
    idx = 0
    for i in range(0, len(input_str)):
        if input_str[i] == '@':
            output_str += str(idx_list[idx])
            idx += 1
        else:
            output_str += input_str[i]
    return output_str

I wonder if there is any shorter and faster way than the concatenation that I have used?

答案1

得分: 1

一个简洁的方法使用 re.sub 与回调函数:

input_str = 'The substring of "python" from index @ to index @ inclusive is "tho"'
idx_list = [2, 4]
output_str = re.sub(r'\bindex @', lambda m: str(idx_list.pop(0)), input_str)
print(output_str)

# "python"从2到4(包括)的子字符串是"tho"

这里的思路是,每当找到 index @ 的匹配时,我们将其替换为索引列表中的第一个条目。然后,我们弹出该索引,以确保它不再被使用。

英文:

One concise approach uses re.sub with a callback function:

<!-- language: python -->

input_str = &#39;The substring of &quot;python&quot; from index @ to index @ inclusive is &quot;tho&quot;&#39;
idx_list = [2, 4]
output_str = re.sub(r&#39;\bindex @&#39;, lambda m: str(idx_list.pop(0)), input_str)
print(output_str)

# The substring of &quot;python&quot; from 2 to 4 inclusive is &quot;tho&quot;

The idea here is that every time a match of index @ is found, we replace with the first entry in the list of indices. We also then pop that first index, so that it doesn't get used again.

答案2

得分: 0

你可以使用格式化字符串吗?
它会像这样:

idx_list = [2, 4]
input_str = f'The substring of "python" from index {idx_list[0]} to index {idx_list[1]} inclusive is "tho"'
英文:

Could you use formatted strings?
It would look like this:

idx_list = [2,4]
input_str = f&#39;The substring of &quot;python&quot; from index {idx_list[0]} to index {idx_list[1]} inclusive is &quot;tho&quot;&#39;

答案3

得分: 0

你基本上是在使用略有不同的格式字符串重新创建str.format()。请参阅https://docs.python.org/3/tutorial/inputoutput.html#the-string-format-method

如果你只想要将格式与Python已经执行的任务完全匹配,只需用{}替换@

input_str = '从索引@到索引@的“python”子字符串是“tho”'
idx_list = [2, 4]
print(input_str.replace('@', '{}').format(*idx_list))

但如果原始字符串非常大,您可能不希望添加替换步骤。由于我们希望在这种情况下更倾向于迭代器,请编写一个生成器来遍历字符串并生成其字符,除了将@替换为idx_list中的下一个参数。

# 我的第一个草稿有点笨拙
def replace_char(input_str, idx_list):
    def replace(s, args):
        for char in s:
            if char == '@':
                yield str(next(args))
            else:
                yield char
    return ''.join(replace(input_str, iter(idx_list)))

input_str = '从索引@到索引@的“python”子字符串是“tho”'
idx_list = [2, 4]
print(replace_char(input_str, idx_list))

这与您的原始代码没有真正的不同。

英文:

You're basically recreating str.format() using a slightly different format string. see https://docs.python.org/3/tutorial/inputoutput.html#the-string-format-method

If you just want to fix the format to exactly match how python already does the task you're doing, just replace '@' with '{}'

input_str = &#39;The substring of &quot;python&quot; from index @ to index @ inclusive is &quot;tho&quot;&#39;
idx_list = [2, 4]
print(input_str.replace(&#39;@&#39;, &#39;{}&#39;).format(*idx_list))

But if the original string is really big, you may not want to add the replace step. Since we want to favor iterators in that case, write a generator to go through the string and yield its characters, except replace '@' with the next argument in your idx_list.

# my first draft is a bit clunky
def replace_char(input_str, idx_list):
    def replace(s, args):
        for char in s:
            if char == &#39;@&#39;:
                yield str(next(args))
            else:
                yield char
    return &#39;&#39;.join(replace(input_str, iter(idx_list)))

input_str = &#39;The substring of &quot;python&quot; from index @ to index @ inclusive is &quot;tho&quot;&#39;
idx_list = [2, 4]
print(replace_char(input_str, idx_list))

This is not really any different from your original code.

答案4

得分: 0

def replace_char(input_str: str, min_index: int, max_index: int) -> str:
    return input_str[:min_index] + '@' * (max_index - min_index) + input_str[max_index:]

input_str = 'The substring of "python" from index @ to index @ inclusive is "tho"'

output_str = replace_char(input_str, 2, 4)
print(output_str)

# Th@@substring of "python" from index @ to index @ inclusive is "tho"  # 'Th@@substring of "python" from index @ to index @ inclusive is "tho"'
英文:

You can use this code.

def replace_char(input_str: str, min_index: int, max_index: int) -&gt; str:
    return input_str[:min_index] + &#39;@&#39; * (max_index - min_index) + input_str[max_index:]

input_str = &#39;The substring of &quot;python&quot; from index @ to index @ inclusive is &quot;tho&quot;&#39;

output_str = replace_char(input_str, 2, 4)
print(output_str)

# Th@@substring of &quot;python&quot; from index @ to index @ inclusive is &quot;tho&quot;  # &#39;Th@@substring of &quot;python&quot; from index @ to index @ inclusive is &quot;tho&quot;&#39;

huangapple
  • 本文由 发表于 2023年3月4日 01:02:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/75629940.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定