python迭代列表和子串

时间:2014-07-21 07:12:23

标签: python string list dictionary substring

我有两个python字典变量。一个是带有ID作为键和长字符串作为值的字典,另一个是带有不同类型ID作为键的dict,列表作为值。

他们看起来像这样:

**dContigData** 
Chromosome_8.8 AAACGCAATAACCAGAAAACCAATTTTTAAAATATTAAACCCAACGAAAT...
Chromosome_8.4 CCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCC...
Chromosome_8.5 CTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCT...
Chromosome_8.6 GCCTGCTCGTAACCCTGACTCGTCCACCCCCAATCCGTCACCCCATTAAT...
Chromosome_8.7 CCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACC...
Chromosome_8.1 TCGCTTCGGCGGTCCTGCGGCATCTTTGTACTTCTTGTGGAAGTCGTCAA...
Chromosome_8.2 CCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACC...
Chromosome_8.3 TAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTAACCCTA...

和另一个:

e = dict() # temporary dictionary variable:
MGG_08464T0 ['Chromosome_8.4', 306312, 306647, 306759, 307475]
MGG_06151T0 ['Chromosome_8.3', 2749586, 2750617]
MGG_07594T0 ['Chromosome_8.3', 1141635, 1142444]
MGG_13455T0 ['Chromosome_8.3', 1512811, 1512907, 1513002, 1513487, 1513578, 1513822, 1514067, 1514645]
MGG_00992T0 ['Chromosome_8.5', 896033, 896144, 896226, 896573, 896655, 897307]
MGG_04622T0 ['Chromosome_8.1', 7084849, 7084958, 7085037, 7085724]

所以,我已经编写了代码来打印来自" dict e"来自" dict e"的dContigData值的子字符串。 value [1] -1(第一种情况下为306311,因python位置减去1)为值[-1](第一种情况下为307475)。然而,列表中的值不是相同的长度,尽管位置信息元素(列表中第一个元素之后的元素,例如Chromosome_8.X)总是成对出现。实际上,我想要做的是迭代每个列表中的位置信息元素,并对dContigData字符串进行子串。

我的代码:

dContigData = readContigFasta()

#for key in dContigData:
#    print(key, dContigData[key][0:50]+"...")

for key in e:
    for contigID in dContigData:
        if e[key][0] == contigID:
            #print (key, e[key])
            print (key, dContigData[contigID][e[key][1]-1:e[key][-1]]) # -1 for start base 0

编辑:好的,很多人都没有得到我的问题,所以如果你不理解上述嘟,,请专注于下面的最终结果,请。 ;)

结果应该是(例如,作为#34中的第5; dict e" 3件):

e.g。

MGG_00992T0 [896032]ATGGGCATTTCGGCTCGGGTCAGTAC[896144]...[896225]GCTGACCCATTACAGGTTGGGGGCTTTAA[896573]...[896654]ACCAAAGTTCCCACTTGTCCCCTGGGACCGAGATGTCCAACAATGA[897307]

[number]和...为了更容易理解(不应该包括在内)

是否有想法对字符串进行子串,然后在循环时连接回字符串?

5 个答案:

答案 0 :(得分:2)

以下是您问题的简化版本,说明了我的内容 你正在寻找基于预编辑的问题,并使用 完整的字母而不是DNA,使位置更清晰。 (请参阅 有关如何编写有用的minimal example的帮助文件。)

dContigData = {
    "chromo_1": "abcdefghij",
    "chromo_2": "ABCDEFGHIJ"
}

e = {
    "mgg_1": ["chromo_1", 2, 4, 7, 9],
    "mgg_2": ["chromo_2", 1, 5, 8, 10]
}

期望的输出:

mgg_1
bcd...ghi
mgg_2
ABCDE...HIJ

如果这是你的意思,这个Python 3代码将产生该输出。 请注意,字典键没有任何特定顺序。你可能更喜欢 从那以后使用e的列表列表,而不是列表的列表 无论如何,你似乎只是在迭代它。

for mgg in sorted(e):
    lst = e[mgg]
    chrom = lst[0]
    substrings = []
    for i in range(1, len(lst), 2):
        startpos, endpos = lst[i:i+2]
        substrings.append(dContigData[chrom][startpos-1:endpos])
    print("{}\n{}".format(mgg, "".join(substrings)))

答案 1 :(得分:1)

如果我理解你的问题,应该这样做:

for key, value in e.items():
    print(
        key,
        dContigData[value[0]][value[1]-1:value[-1]]
    )

答案 2 :(得分:1)

“有什么想法对字符串进行子串,然后在循环时连接回字符串?”

不知道我是否理解你的问题,但是

# sep = "..."
for key in e:
    for contigID in dContigData:
        if e[key][0] == contigID:
            dnaSeq = ''
            starts = [x-1 for x in e[key][1::2]]
            ends =  e[key][2::2]
            for i in range(len(starts)):
                dnaSeq += dContigData[contigID][starts[i]:ends[i]]
                #if i<len(starts)-1:
                #   dnaSeq += sep 
            print (key, '\n', dnaSeq)

应该带给你假设的结果。

更新: 考虑到您的上一次编辑,您可以跳过“sep”步骤,您将获得dnaSeq,这些部分之间没有任何分隔符。

答案 3 :(得分:1)

根据您的修改,我认为这应该做您需要的。我使用Tom's simplified version of your question更明确地解释了事情

dContigData = {
    "chromo_1": "abcdefghij",
    "chromo_2": "ABCDEFGHIJ"
}

e = {
    "mgg_1": ["chromo_1", 2, 4, 7, 9],
    "mgg_2": ["chromo_2", 1, 5, 8, 10]
}

# Iterate over the items (keys/values) of e dictionary
for key, value in e.items():
    # Store in a variable for easier understanding
    string = dContigData[value[0]]
    # Get a list of tuples of (start, end) positions for the substrings
    # Example for mgg_1: zip([2,7], [4,9]) = [(2,4), (7,9)] 
    subPositions = zip(value[1::2], value[2::2])
    # Join the substrings for all these pairs
    # (most efficient string concatenation)
    res = ''.join([string[val[0]-1:val[1]] for val in subPositions])
    print key
    print res

输出:

mgg_2
ABCDEHIJ
mgg_1
bcdghi

这不能保证迭代的顺序,所以如果这对你很重要,你可以简单地使用一个排序的迭代器iter(sorted(e.items()))

答案 4 :(得分:1)

更通用的解决方案:

import itertools


def group(lst, n):
    """Group an iterable into an n-tuples iterable. Incomplete tuples
    are discarded e.g.

    >>> list(group(range(10), 2))
    [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)]
    >>> list(group(range(10), 3))
    [(0, 1, 2), (3, 4, 5), (6, 7, 8)]
    """
    return itertools.izip(*[itertools.islice(lst, i, None, n)
                          for i in range(n)])


for key in e:
    sub_str_list = []
    contigID = e[key][0]
    for start, end in group(e[key][1:], 2):
        sub_str_list.append(dContigData[contigID][start-1:end])
    print(contigID, '...'.join(sub_str_list))