【问题标题】:Replace multiple equal strings in a word with list of strings from JSON用 JSON 中的字符串列表替换单词中的多个相等字符串
【发布时间】:2019-08-04 04:20:38
【问题描述】:

我在使用脚本将普通字母替换为特殊字符以测试翻译系统时遇到问题,这是一个示例(cha-mate 是 chá-mate,但将使用 chã-mate/chã-máte 等进行测试变体),但不是创建这种变体,而是将所有相同的字符切换为仅一个特殊字母,这是它正在打印的内容:

chá-máte
chã-mãte

这是理论上应该打印的内容:

cha-máte
cha-mãte
chá-mate
chã-mate
etc.

这是代码和使用的 json:

def translation_tester(word):
    esp_chars = {
        'a': 'áã',
    }

    #words = [word]
    for esp_char in esp_chars:
        if esp_char in word:
            replacement_chars = esp_chars[esp_char]
            for i in range(len(replacement_chars)):
                print(word.replace(esp_char, replacement_chars[i]))

def main():
    words = ['cha-mate']
    for word in words:
        translation_tester(word)

main()

无论如何,任何帮助表示赞赏,在此先感谢!

【问题讨论】:

  • 你的规格有点混乱。为什么不也cha-mate、cha-máte、cha-mãte?为什么你只改变第二个a而不改变第一个a?如果确实预期的结果数是 9,那么它基本上是一个排列。
  • @Spinor8 很抱歉,如果它令人困惑,tbh 你呈现的方式会工作正常,现在要编辑规格,以便更清楚,谢谢!

标签: python json python-3.x for-loop


【解决方案1】:

要处理任意数量的替换,您需要使用递归。我就是这样做的。

intword = 'cha-mate'
esp_chars = {'a': 'áã'}

def wpermute(word, i=0):
    for idx, c in enumerate(word[i:], i):
        if c in esp_chars:
            for s in esp_chars[c]:
                newword = word[0:idx] + s + word[idx + 1:]
                wpermute(newword, idx + 1)
        if idx == len(word) -1:
            print(word)

wpermute(intword)

它给出了单词的 9 种不同书写方式的输出。

chá-máte
chá-mãte
chá-mate
chã-máte
chã-mãte
chã-mate
cha-máte
cha-mãte
cha-mate

【讨论】:

  • 非常感谢这个例子!其余的东西很容易实现。
  • 我做了一些更改,以便尝试了解代码是如何完全工作的,但我对两个部分有疑问,这是我的 cmets 和编辑,希望您能给我一些解释或给我一些再次阅读有关它的材料,非常感谢您提供的示例!
  • 您有什么疑问?这个想法是我每次遇到 esp_chars 时都会分成多个分支。在第一个“a”之后,它分成 3 个分支。在第二个“a”之后,3 个分支中的每一个都拆分为另外 3 个。所以总共有 9 个。每次拆分时,我都会在下一个索引处开始新的计数。您可以看到枚举不是从零开始的,除非它正好在开头。这是一个关于递归的链接,它非常好,但并没有完全涵盖上述情况。 realpython.com/python-thinking-recursively
  • 一个好的调试器会帮助你理解代码是如何工作的。我个人使用 PyCharm。放置断点并查看变量如何流动。当然,你应该先阅读上面关于递归的内容。否则树状遍历会让你感到困惑。
  • 我刚刚看到您尝试的一些编辑。让我尝试解决它们。 wpermute(newword, idx + 1) 是递归。函数 wpermute 再次调用自身。阅读上面的链接。 if idx == len(word) -1: 当迭代到达单词的末尾时。在这种情况下,我们将其打印出来。
【解决方案2】:

可能有更好的方法来做到这一点,但您可以执行以下操作(确保在替换字符列表中包含纯“a”):

import itertools
import re

def replace_at_indices(word, new_chars, indices):
  new_word = word
  for i, index in enumerate(indices):
    new_word = new_word[:index] + new_chars[i] + new_word[index+1:]
  return new_word

def translation_tester(word):
    esp_chars = {
        'a': 'aáã',
    }

    for esp_char in esp_chars:
      replacement_chars = list(esp_chars[esp_char])
      indices = [m.start() for m in re.finditer(esp_char, word)]
      product = list(itertools.product(replacement_chars, repeat=len(indices)))
      for p in product:
        new_word = replace_at_indices(word, p, indices)
        print(new_word)

def main():
    words = ['cha-mate']
    for word in words:
        translation_tester(word)

main()

对于你的例子,这应该给你:

cha-mate
cha-máte
cha-mãte
chá-mate
chá-máte
chá-mãte
chã-mate
chã-máte
chã-mãte

另见:

Find all occurrences of a substring in Python

generating permutations with repetitions in python

Replacing a character from a certain index

【讨论】:

  • 感谢您的示例和链接,那里有一些不错的东西!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
  • 2021-06-12
  • 1970-01-01
  • 2020-08-31
  • 2019-01-29
相关资源
最近更新 更多