【问题标题】:Python3 replace using dictionaryPython3 使用字典替换
【发布时间】:2023-07-19 14:07:01
【问题描述】:

谁能解释一下这里出了什么问题:

def get_complementary_sequence(string):
    dic = {'A':'T', 'C':'G', 'T':'A', 'G':'C'}
    for a, b in dic.items():
        string = string.replace(a, b)
    return string

我得到了“T”和“C”的正确结果,但“A”和“C”不会替换。真的卡住了。

字符串看起来像“ACGTACG”。

【问题讨论】:

  • 您正在按顺序遍历字典的每个项目,因此它们都被正确替换了!问题是当你替换 T 时,A 已经被 T 替换了,所以你把它替换回来。
  • 既然你正在尝试处理DNA序列,我建议你改用BioPython

标签: python string python-3.x replace


【解决方案1】:

您首先将所有As 替换为Ts,然后再将所有Ts 替换为As(包括您刚刚替换As 的那些!):

>>> string = 'ACGTACG'
>>> string.replace('A', 'T')
'TCGTTCG'
>>> string.replace('A', 'T').replace('T', 'A')
'ACGAACG'

改用翻译地图,馈送到str.translate()

transmap = {ord('A'): 'T', ord('C'): 'G', ord('T'): 'A', ord('G'): 'C'}
return string.translate(transmap)

str.translate() 方法需要将代码点(整数)映射到替换字符(单个字符或代码点)或 None(从输入字符串中删除代码点)的字典。 ord() 函数为我们提供了给定“发件人”字母的代码点。

这会在翻译映射中逐一查找string 中的字符,而不是替换所有As 后跟所有Ts。

str.translate() 具有比一系列str.replace() 调用快得多的额外优势。

演示:

>>> string = 'ACGTACG'
>>> transmap = {ord('A'): 'T', ord('C'): 'G', ord('T'): 'A', ord('G'): 'C'}
>>> string.translate(transmap)
'TGCATGC'

【讨论】:

  • str.translate() 也比天真的''.join(dic[c] for c in s) 快得多。
【解决方案2】:

可变数据是你的敌人 :)

看,你首先将所有As 替换为Ts,然后,在另一个迭代中,再次将所有Ts 替换为As。

什么有效:

# for Creek and Watson's sake, name your variables sensibly
complements = {ord('A'):'T', ord('C'):'G', ord('T'):'A', ord('G'):'C'}
sequence = "AGCTTCAG"
print(sequence.translate(complements))

它打印TCGAAGTC

【讨论】: