遍历现有键并更新字典python
Posted
技术标签:
【中文标题】遍历现有键并更新字典python【英文标题】:iterate through existing keys and update dictionary python 【发布时间】:2014-05-04 02:59:35 【问题描述】:我正在编写一个简单的脚本,该脚本循环遍历字符串,在本例中为来自文件的 dna 序列,并计算每个 dna 字符串的词频(每次相同的词列表,新的值列表)。 我的方法(见下文)使用字典将单词存储为键,并将每个单词的频率存储为值,但我一直在尝试向现有键添加新值(针对每个后续 dna 记录)。
record1 足够简单(类似于“GTACGTACATTT...”),我的字典看起来像:
'GTAC':'2','ATTT':1,....
然后对于 $foo 中的任何其他记录,我想更新这个字典(包含相同的键): 'GTAC':'2','1',...,'ATTT':1,0,...
from Bio import SeqIO
def tetra_freq(sequence):
counts =
for record in SeqIO.parse(sequence, 'fasta'):
newseq=record.seq
for base1 in ['A', 'T', 'G', 'C']:
for base2 in ['A', 'T', 'G', 'C']:
for base3 in ['A', 'T', 'G', 'C']:
for base4 in ['A','T','G','C']:
tetranucleotide = base1 + base2 + base3 + base4
count = newseq.count(tetranucleotide)
if tetranucleotide in counts.keys():
counts.update(count)
else:
counts[tetranucleotide] = count
print(counts)
tetra_freq('$foo')
【问题讨论】:
神圣的巢穴,蝙蝠侠! 字典的update
函数需要字典作为输入:counts.update(tetranucleotide: count)
。幸运的是,这将为您更新或创建密钥。
您可以使用 itertools.product('ATGC', repeat=4) 而不是那种讨厌的嵌套,物有所值。
感谢@JackGibbs,嵌套是基于我在网上找到的生物学家的 python 入门。主要障碍仍然存在..
@Thane Brimhall 感谢您的评论。不幸的是,这似乎只是将一个记录中的值添加到前一个记录(即 GTAC:1,TTAA:2 变为 GTAC:2,TTAA:4 而不是 GTAC:1,1,TTAA:2,2
【参考方案1】:
据我了解,你有一个词,说:
“GTACATTTCATGATTT”
这给了你:
'GTAC' : 1, 'ATTT': 2, 'CATG': 1
那么,如果你看到另一个词,说:
“GTACAATC”
你现在有:
'GTAC' : [1, 1], 'ATTT' : [2, 0], 'CATG' : [1, 0], 'AATC' : [0, 1]
等等?如果我误解了,我会编辑我的回复。无论如何,应该这样做:
from itertools import product
strings = ["GTACATTTCATGATTT", "GTACAATC"]
count_dict =
for poss_word in product('ATCG', repeat=4):
count_dict["".join(poss_word)] = [0] * len(strings)
for index, string in enumerate(strings):
while string:
word = string[:4]
count_dict[word][index] += 1
string = string[4:]
将事物明显提取到函数中,而不是什么。
【讨论】:
【参考方案2】:从你的描述中看不完全清楚你是否只看四个字母对齐的单词,即
"GTACGTACATTT" => "GTAC", "GTAC", "ATTT"
(正如您的字典计数所暗示的那样),或者您是否正在查看任何四个字母序列,
"GTACGTACATTT" => "GTAC", "TACG", "ACGT", "CGTA", "GTAC", "TACA", "ACAT", "CATT", "ATTT"
正如您使用str.count
似乎暗示的那样。请注意,如果是后者,str.count
仅计算 非重叠 实例 - 所以 "AAAAAAA".count("AAAA")
返回 1 而不是您预期的 4!
# assumes Python 2.7
from Bio import SeqIO
from collections import Counter
from itertools import izip, product, tee
def get_aligned_quads(seq, length=4):
args = [iter(seq)] * length
return (''.join(letters) for letters in izip(*args))
def get_unaligned_quads(seq, length=4):
args = tee(iter(seq), length)
for steps,arg in enumerate(args):
for step in range(steps):
next(arg, None)
return (''.join(letters) for letters in izip(*args))
all_quads = [''.join(seq) for seq in product("ACGT", repeat=4)]
def quad_freq(sequence, aligned=True):
get_quads = get_aligned_quads if aligned else get_unaligned_quads
counts = quad:[] for quad in all_quads
for i,record in enumerate(SeqIO.parse(sequence, 'fasta')):
for quad in all_quads:
counts[quad].append(0)
for quad in get_quads(record.seq):
counts[quad][i] += 1
return counts
print(quad_freq("$foo"))
编辑:我将 all_quads 转换为列表 - 应该会快一点;
我还做了一些模拟,发现(假设统一随机输入)使用 .count 少报了大约 1.049% 的基因计数。显然,某些类型的四边形比其他类型的受影响更大:
4 个相同的四边形 (“AAAA”) 被低估 1/4 (25%) - 也就是说,每次它们后跟同一个字母时。这会影响 4 / 256 个四边形,导致总基因数减少 0.39%。
2 对的四边形(“ATAT”)被低估了 1/16(6.25%) - 每次它们后跟相同的字母对时。这会影响 12 / 256 个四边形(忽略同样是 4 个的四边形),导致总基因数减少 0.29%。
第一个字母与最后一个字母相同的四边形(“AGTA”)被低估了 1/64 (1.56%) - 每次它们后跟前三个字母。这会影响 60 / 256 个四边形(忽略也是 4 个相同的四边形),导致总基因数减少 0.37%。请注意,(2-pairs - 4-the-same) 和 (first-and-last - 4-the-same) 之间没有重叠。
不符合上述任何一项的四边形不受影响;这是剩下的 180 / 256 个四边形。
【讨论】:
感谢@Hugh Bothwell,指出 .count 仅给出对齐的字数。我实际上需要您的脚本提供的未对齐版本。但是,我遇到了关键错误:文件“Untitled 5.py”,第 27 行,在 quad_freq counts[quad][i] += 1 KeyError: 'ATAA'" 我的错误:我从 all_quads() 而不是 'ATAA' 返回 ie ('A', 'T', 'A', 'A')。现在应该修好了。以上是关于遍历现有键并更新字典python的主要内容,如果未能解决你的问题,请参考以下文章
遍历数据框和字典以更新数据框中的值,以便与 python 匹配字符串