尝试转换RNA字符串时出现不可哈希类型错误
在我现在正在写的代码里,有一个叫做codon_dict的字典,这个字典里列出了所有三字母密码子(codon)以及它们对应的氨基酸。我还有一个表格叫做rnaCodonTable,里面的值是单字母的氨基酸,而键是对应的三字母密码子。我想做的是从一个RNA碱基字符串中,每三个碱基对识别为一个密码子,然后把它翻译成它们所代表的单字母氨基酸。这是我目前的设置:
for i in range (0, len(self.codon_dict), 3):
codon = self.codon_dict[i:i+3]
print (codon)
if codon in NucParams.codon_dict():
self.codon_dict[codon] +=1
#codons are then converted to amino acids.
temp_aa = NucParams.rnaCodonTable(codon)
if temp_aa in self.aa_dict:
self.aa_dict[temp_aa] += 1
我遇到了这个错误信息:codon = self.codon_dict[i:i+3] TypeError: unhashable type: 'slice'
我不太明白我哪里出错了。有人能给我解释一下这个错误吗?
这是rnaCodonTable的样子:
rnaCodonTable = {
# RNA codon table
# U
'UUU': 'F', 'UCU': 'S', 'UAU': 'Y', 'UGU': 'C', # UxU
'UUC': 'F', 'UCC': 'S', 'UAC': 'Y', 'UGC': 'C', # UxC
'UUA': 'L', 'UCA': 'S', 'UAA': '-', 'UGA': '-', # UxA
'UUG': 'L', 'UCG': 'S', 'UAG': '-', 'UGG': 'W', # UxG
# C
'CUU': 'L', 'CCU': 'P', 'CAU': 'H', 'CGU': 'R', # CxU
'CUC': 'L', 'CCC': 'P', 'CAC': 'H', 'CGC': 'R', # CxC
'CUA': 'L', 'CCA': 'P', 'CAA': 'Q', 'CGA': 'R', # CxA
'CUG': 'L', 'CCG': 'P', 'CAG': 'Q', 'CGG': 'R', # CxG
# A
'AUU': 'I', 'ACU': 'T', 'AAU': 'N', 'AGU': 'S', # AxU
'AUC': 'I', 'ACC': 'T', 'AAC': 'N', 'AGC': 'S', # AxC
'AUA': 'I', 'ACA': 'T', 'AAA': 'K', 'AGA': 'R', # AxA
'AUG': 'M', 'ACG': 'T', 'AAG': 'K', 'AGG': 'R', # AxG
# G
'GUU': 'V', 'GCU': 'A', 'GAU': 'D', 'GGU': 'G', # GxU
'GUC': 'V', 'GCC': 'A', 'GAC': 'D', 'GGC': 'G', # GxC
'GUA': 'V', 'GCA': 'A', 'GAA': 'E', 'GGA': 'G', # GxA
'GUG': 'V', 'GCG': 'A', 'GAG': 'E', 'GGG': 'G' # GxG
}
1 个回答
1
有人能给我解释一下这个错误吗?
字典是一种用来查找的工具,字典里的“键”必须是可以被哈希的。在你的代码中,i:i:3
的值是一个不可哈希的类型,叫做切片,所以它不能作为字典的键。
这里有一个简化版的错误示例,使用了另一种不可哈希的类型,列表:
>>> d = {} # An empty dictionary
>>> d[[1,2]] = 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
我想我明白你想做什么,你有一个字符串,表示一个RNA链,像这样:
s = 'AUUGCUAAAAAGGAGGAUUUUCG'
你想从rnaCodonTable
字典中获取对应的密码子。
所以,问题在于把RNA链分成三个字母一组,这样你就可以在密码子表中查找:
为了简化操作,可以使用grouper
的用法:
from itertools import izip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
s = 'AUUGCUAAAAAGGAGGAUUUUCG'
codons = []
for pair in grouper(s, 3):
codons.append(rna_codon_table[''.join(pair)])
print('Codons: {}'.format(''.join(codons))
grouper
会返回一个元组,而我们的键是字符串,所以我们用一个空字符串把元组连接起来,形成一个三字母的组合:
>>> for pair in grouper(s, 3):
... print(pair)
...
('A', 'U', 'U')
('G', 'C', 'U')
('A', 'A', 'A')
('A', 'A', 'A')
('G', 'G', 'A')
('G', 'G', 'U')
('U', 'U', 'U')
('U', 'C', 'G')
>>> for pair in grouper(s,3):
... print(''.join(pair))
...
AUU
GCU
AAA
AAA
GGA
GGU
UUU
UCG
接下来,我们获取每个三字母组合对应的密码子,并把它们存储在一个列表中。最后,我们把这个列表打印出来,作为一个字符串。
你可以把循环合并成一个生成器,然后直接使用它,像这样:
codons = ''.join(rna_codon_table[''.join(pair)] for pair in grouper(s, 3))
我根据Python风格指南修改了你字典的命名方式。