这个答案与 Brian 的 answer 非常相似,但经过了一些处理,并且输出没有重复:
words = ["Words", "Shirt", "Blouse", "Sweater"]
md = {"e": "q,w", "a": "z"}
md = {k: v.split(',') for k, v in md.items()}
newwords = []
for word in words:
newwords.append(word)
for c in md:
occ = word.count(c)
pos = 0
for _ in range(occ):
pos = word.find(c, pos)
for r in md[c]:
tmp = word[:pos] + r + word[pos+1:]
newwords.append(tmp)
pos += 1
newwords的内容:
['Words', 'Shirt', 'Blouse', 'Blousq', 'Blousw', 'Sweater', 'Swqater', 'Swwater', 'Sweatqr', 'Sweatwr', 'Swezter']
漂亮的打印:
Words
Shirt
Blouse
Blousq
Blousw
Sweater
Swqater
Swwater
Sweatqr
Sweatwr
Swezter
任何错误都是当前时间的结果。 ;)
更新(说明)
tl;dr
主要思想是逐个查找单词中字符的出现。对于每一次出现,我们都用替换字符替换它(一次又一次)。被替换的单词 get 被添加到输出列表中。
我会尝试一步一步解释一切:
words = ["Words", "Shirt", "Blouse", "Sweater"]
md = {"e": "q,w", "a": "z"}
嗯。您的基本输入。 :)
md = {k: v.split(',') for k, v in md.items()}
处理替换字典的更简单方法。 md 现在看起来像 {"e": ["q", "w"], "a": ["z"]}。现在我们不必以不同的方式处理"q,w" 和"z",但是替换的步骤是一样的,并且忽略了"a" 只有一个替换字符这一事实。
newwords = []
存储输出的新列表。
for word in words:
newwords.append(word)
我们必须对每个单词执行这些操作(我想,原因很清楚)。我们还将世界直接附加到我们刚刚创建的输出列表 (newwords)。
for c in md:
c 是 character 的缩写。因此,对于我们要替换的每个字符(md 的所有键),我们执行以下操作。
occ = word.count(c)
occ 代表occurrences(是的。count 也适合:P)。 word.count(c) 返回字符/字符串c 在word 中的出现次数。所以"Sweater".count("o") => 0 和"Sweater".count("e") => 2。
我们在这里使用它来了解,我们必须多久查看一次word 才能获得所有c 的出现次数。
pos = 0
我们的起始位置是在word 中寻找c。在下一个循环中使用。
for _ in range(occ):
对于每次出现。由于连续数字在这里对我们没有价值,我们将其命名为_ 来“丢弃”它。此时c 在word 中。然而。
pos = word.find(c, pos)
哦。看。我们找到了c。 :) word.find(c, pos) 返回c 在word 中第一次出现的索引,从pos 开始。在开头,这意味着从字符串的开头 => 第一次出现c。但是通过这个电话,我们已经更新了pos。这加上最后一行 (pos += 1) 将我们的搜索窗口移动到下一轮的搜索窗口,使其刚好在上一次出现的 c 之后开始。
for r in md[c]:
现在您明白了,为什么我们之前更新了 mc:我们现在可以轻松地对其进行迭代(旧的 md 上的 md[c].split(',') 也可以完成这项工作)。所以我们现在对每个替换字符进行替换。
tmp = word[:pos] + r + word[pos+1:]
实际替换。我们将其存储在tmp(出于调试原因)。 word[:pos] 给我们word 直到c 的(当前)出现(独家c)。 r 是替代品。 word[pos+1:] 添加剩余的单词(同样没有c)。
newwords.append(tmp)
我们如此创建的新词 tmp 现在进入我们的输出列表 (newwords)。
pos += 1
已经提到的将pos 调整为“跳过c”。
来自 OP 的附加问题: 有没有一种简单的方法来指定我要替换的字符串中有多少个字母 [(意思是一次多个)]?
当然。 但我目前对如何实现这一点只有一个模糊的想法。我去看看,等我睡着了。 ;)
words = ["Words", "Shirt", "Blouse", "Sweater", "multipleeee"]
md = {"e": "q,w", "a": "z"}
md = {k: v.split(',') for k, v in md.items()}
num = 2 # this is the number of replaces at a time.
newwords = []
for word in words:
newwords.append(word)
for char in md:
for r in md[char]:
pos = multiples = 0
current_word = word
while current_word.find(char, pos) != -1:
pos = current_word.find(char, pos)
current_word = current_word[:pos] + r + current_word[pos+1:]
pos += 1
multiples += 1
if multiples == num:
newwords.append(current_word)
multiples = 0
current_word = word
newwords的内容:
['Words', 'Shirt', 'Blouse', 'Sweater', 'Swqatqr', 'Swwatwr', 'multipleeee', 'multiplqqee', 'multipleeqq', 'multiplwwee', 'multipleeww']
漂亮的打印:
Words
Shirt
Blouse
Sweater
Swqatqr
Swwatwr
multipleeee
multiplqqee
multipleeqq
multiplwwee
multipleeww
我添加了multipleeee 来演示替换是如何工作的:对于num = 2,这意味着前两个出现被替换,在它们之后,接下来的两个被替换。所以更换的零件没有交叉点。如果您想要['multiplqqee', 'multipleqqe', 'multipleeqq'] 之类的内容,则必须存储char 的“第一次”出现的位置。然后您可以将pos 恢复到if multiples == num:-block 中的那个位置。
如果您还有其他问题,请随时提问。 :)