【问题标题】:python iterate list and substringpython迭代列表和子字符串
【发布时间】:2014-07-21 07:12:23
【问题描述】:

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

它们看起来像这样:

**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”值[1]-1(第一种情况下为 306311,由于 python 位置而减去 1)中的 dContigData 值的子字符串到值[-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

编辑:好的,你们中的许多人不明白我的问题,所以如果你不理解上面的喃喃自语,请专注于下面的最终结果。 ;)

结果应该是(例如“dict e”中的第 5 个,有 3 个):

例如

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

[number] 和 ... 以便于理解(应该不包括在内)

有什么想法可以在循环时对字符串进行子串化,然后再连接回字符串?

【问题讨论】:

  • 对您的代码的评论:您不需要内部循环,使用 e[key][0] 而不是 contigID。那我没看懂你的问题,你说的位置信息元素是什么意思?你能解释一下你想要再次实现的目标吗?我想这与列表中的位置编号有关,而不是第一个和最后一个元素,但我不确定你想如何使用它们。
  • 感谢您对@Thibault 的关注。为了更容易理解,我稍微改变了这个问题。我想做的是用上面的位置信息切割字符串并将切割的字符串连接成一个。

标签: python string list dictionary substring


【解决方案1】:

这是您问题的简化版本,说明了我的问题 认为您正在寻找基于预编辑问题,并使用 完整的字母表而不是 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)))

【讨论】:

  • 感谢您的回答。你理解的很到位。但是,...是不必要的("".join(substrings) 可以),并且您的输出结果是 chromo_1 bcdghi / chromo_2 ABCDEHIJ,而不是 mgg。
  • mcve +1,它甚至帮助我理解了 OP 想要什么并提出另一个答案。 @Karyo 这是一个小错字,打印 mgg 而不是打印 chrom
  • @Karyo:哎呀,忽略了那里使用错误的变量。谢谢。修复了这两个点。
【解决方案2】:

如果我正确理解您的问题,应该这样做:

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

【讨论】:

    【解决方案3】:

    更通用的解决方案:

    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))
    

    【讨论】:

      【解决方案4】:

      根据您的编辑,我认为这应该可以满足您的需求。我使用了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()))

      【讨论】:

        【解决方案5】:

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

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

        # 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,而片段之间没有任何分隔符。

        【讨论】:

          猜你喜欢
          • 2021-04-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多