将列表a中的字符替换为列表b中的字符

时间:2015-05-06 12:31:48

标签: python list

我有两个文本文件:

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 个答案:

答案 0 :(得分: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映射到要替换它的字符串,在python 2中我们做类似的事情,但必须使用string.maketrans创建我们的表最终成为字符串'#*%', 'AMN'

答案 1 :(得分: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)

答案 2 :(得分:0)

有很多方法可以做到这一点,并且可能存在各种限制。与单词文件的大小一样,线索是否总是2个字符,第一个字符是要替换的,第二个字符是要替换的。这是一个简单的解决方案,您可以构建它。

不是将单词读入列表,而是首先将其作为字符串读取(假设文件大小合理),然后将其替换为线索,然后将其拆分。因此,每条线索只能替换一次。像:

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

答案 3 :(得分: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]