用列表b中的字符替换列表a中的字符

3
我有两个文本文件:
clues.txt - 包含字母/符号对:
A#
M*
N%

words.txt - 包含了一系列被打乱的单词列表:
#+/084&"
#3*#%#+
8%203:
,1$&
!-*%
.#7&33&
#*#71%
&-&641'2
#))85
9&330*

我使用列表推导式将每个文件的内容读入一个列表中:
clues = [line.strip() for line in open("clues.txt", 'r')]

words = [line.strip() for line in open("words.txt", 'r')]

我该如何动态替换“words”列表中每个符号的所有实例,以匹配“clues”列表中对应的符号?
因此,“words”中的每个“#”实例都将替换为“A”,“words”中的每个“*”实例都将替换为“M”,依此类推。
4个回答

4

您可以使用str.replace将每行线索中的子字符串创建成对,然后迭代重新分配行,以替换后的行的更新值为新值:

with  open("clues.txt", 'r') as f, open("words.txt", 'r') as f2:
    clues = [list(line.rstrip()) for line in f]
    for line in f2:
        for rep, orig in clues:
            line = line.replace(orig, rep)
        print(line.rstrip())

输出:

A+/084&"
A3MANA+
8N203:
,1$&
!-MN
.A7&33&
AMA71N
&-&641'2
A))85
9&330M

或者使用str.translate

with  open("clues.txt", 'r') as f, open("words.txt", 'r') as f2:
    # keys are ord of character to replace, 
    # values are character to replace with
    d = {ord(k): v for v, k in (list(line.rstrip()) for line in f)}
    for line in f2:
        print(line.translate(d).rstrip())

输出:

A+/084&"
A3MANA+
8N203:
,1$&
!-MN
.A7&33&
AMA71N
&-&641'2
A))85
9&330M

对于Python2,您需要使用string.maketrans来创建表:

from string import maketrans
with open("clues.txt", 'r') as f, open("words.txt", 'r') as f2:
    # separate A -> # ...
    a, b = zip(*(list(line.rstrip()) for line in f))
    # create table where # maps to A, * -> M and % -> N
    tbl = maketrans("".join(b), "".join(a))
    for line in f2:
        # translate each string using our mapping table
        print(line.translate(tbl).rstrip())

输出:

A+/084&"
A3MANA+
8N203:
,1$&
!-MN
.A7&33&
AMA71N
&-&641'2
A))85
9&330M

Python3要求将要替换的字符的ord映射到要替换成的字符串,而在Python2中,我们也需要做类似的操作,但必须使用string.maketrans来创建表格,最终得到的字符串是'#*%', 'AMN'


1

最有效的方法是使用 string.translate 函数:

import string

with open('clues.txt', 'r') as cluesf, open('words.txt', 'r') as wordsf:
    clues = [line.strip() for line in cluesf]
    trans = string.maketrans(''.join([c[1:] for c in clues]), ''.join([c[0] for c in clues]))
    words = [line.strip().translate(trans) for line in wordsf]

    print(words)

0

有很多方法可以做到这一点,也可能存在各种限制。例如单词文件的大小,提示是否总是由两个字符组成,第一个字符是要替换的字符,第二个字符是要替换为的字符。以下是一个简单的解决方案,您可以在此基础上构建。

不要将单词读入列表中,而是首先将其作为字符串读入(假设文件大小合理),然后用提示替换它,最后再拆分它。这样,您就可以每个提示只替换一次。例如:

with open('words.txt') as wfd: file_as_string = wfd.read()
for clue in clues: words_str = file_as_string.replace(clue[1], clue[0])
words = [word.strip() for word in file_as_string.split('\n')]

0

首先将你的clues转换为实际键/值对的映射:

clues = [line.strip() for line in open("clues.txt", 'r')]
clues = dict([(k, v) for v, k in clues])

然后迭代遍历 words 中每个单词的每个字符:

for word in words:
    for i, c in enumerate(word):
        if c in clues:
            word[i] = clues[c]

不幸的是,这并不是最有效率的方法,最坏情况下复杂度为O^2

更新:改进版本如下:

clues = dict([(k, v) for v, k in map(str.strip, open("clues.txt", "r"))])
with open("words.txt", "r") as f:
    for i, c in enumerate(word):
        if c in clues:
            word[i] = clues[c]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接