python - 替换嵌套的 for 循环和列表理解的值分配

标签 python for-loop optimization list-comprehension

我编写了一个函数来计算某些字符(ACGT) 在同一位置的多个字符串中,并将出现的次数保存在字典中。

例如对于这两个字符串 'ACGG' 和 'CAGT',它应该返回:

{'A': [1, 1, 0, 0], 'C': [1, 1, 0, 0], 'G': [0, 0, 2, 1], 'T': [0, 0, 0, 1]}

我想将下面的代码转换为列表理解以优化它的速度。它使用两个嵌套的 for 循环,输入的 Motifs 是包含 A's C's G's 和 T's 的字符串列表。

def CountWithPseudocounts(Motifs):
    count = {}
    k = len(Motifs[0])
    t = len(Motifs)
    for s in 'ACGT':
        count[s] = [0] * k
    for i in range(t):
        for j in range(k):
            symbol = Motifs[i][j]
            count[symbol][j] += 1
return count

我已经尝试为这个列表理解替换函数底部的嵌套 for 循环:

count = [ [ count[Motifs[i][j]][j] += 1 ] for i in range(0, t) ] for j in range(0, k)]

它不起作用,可能是因为我不允许在列表推导中进行 += 1 的赋值。我该如何解决这个问题?

最佳答案

你可以使用zip():

In [10]: a = 'ACGG'           

In [11]: b = 'CAGT'

In [12]: chars = ['A', 'C', 'G', 'T'] 

In [13]: [[(ch==i) + (ch==j) for i, j in zip(a, b)] for ch in chars]
Out[13]: [[1, 1, 0, 0], [1, 1, 0, 0], [0, 0, 2, 1], [0, 0, 0, 1]]

如果你想要一本字典,你可以使用字典理解:

In [25]: {ch:[(ch==i) + (ch==j) for i, j in zip(a, b)] for ch in chars}
Out[25]: {'T': [0, 0, 0, 1], 'G': [0, 0, 2, 1], 'C': [1, 1, 0, 0], 'A': [1, 1, 0, 0]}

或者,如果您希望结果与字符列表的顺序相同,您可以使用 collections.OrderedDict:

In [26]: from collections import OrderedDict

In [27]: OrderedDict((ch, [(ch==i) + (ch==j) for i, j in zip(a, b)]) for ch in chars)
Out[28]: OrderedDict([('A', [1, 1, 0, 0]), ('C', [1, 1, 0, 0]), ('G', [0, 0, 2, 1]), ('T', [0, 0, 0, 1])])

如果您仍然需要更高的性能和/或您正在处理长字符串和更大的数据集,您可以使用 Numpy 通过矢量化方法来解决这个问题。

In [61]: pairs = np.array((list(a), list(b))).T

In [62]: chars
Out[62]: 
array(['A', 'C', 'G', 'T'], 
      dtype='<U1')

In [63]: (chars[:,None,None] == pairs).sum(2)
Out[63]: 
array([[1, 1, 0, 0],
       [1, 1, 0, 0],
       [0, 0, 2, 1],
       [0, 0, 0, 1]])

关于python - 替换嵌套的 for 循环和列表理解的值分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42672276/

相关文章:

python - Python 的嵌套循环结果聚集在一起

python - `scipy.optimize.minimize` 中的 Jacobian 和 Hessian 输入

c# - MethodImpl(No Optimization) 在这个方法上,它做了什么?而且真的有必要吗?

Python 将数据写入文件仅在从控制台运行时有效

python - 加速 CSV 更新/导入 Django 模型

python - 在多列中查找匹配值并返回匹配的列头

python - 将 shlex 置于 Debug模式

c - 用于循环数组?

java - 有人可以帮忙将这个 For 循环快捷方式转换为正常状态吗

math - 英特尔MKL与AMD Math Core库