遍历现有键并更新字典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 匹配字符串

当数据具有现有键时更新嵌套字典

使用要设置的字符串元组更新 Python 字典(键、值)失败

python3字典遍历

在 Pandas Dataframe 中查找多个字典键并返回多个匹配值