2

我在使用下面的一段代码时遇到了一些麻烦:

输入: li 是一个嵌套列表,如下所示:

li = [['>0123456789 mouse gene 1\n', 'ATGTTGGGTT/CTTAGTTG\n', 'ATGGGGTTCCT/A\n'],   ['>9876543210 mouse gene 2\n', 'ATTTGGTTTCCT\n', 'ATTCAATTTTAAGGGGGGGG\n']]

使用下面的函数,在整个子列表中存在的“/”数量大于 1 的情况下,我想要的输出只是“>”后面的第 2 到第 9 位数字。

相反,我的代码将数字提供给所有条目。此外,它给了他们多次。因此,我认为我的计数器和 for 循环有问题。我无法完全弄清楚这一点。

任何帮助,非常感谢。

import os

cwd = os.getcwd()


def func_one():
    outp = open('something.txt', 'w')       #output file
    li = []
    for i in os.listdir(cwd):           
        if i.endswith('.ext'):
            inp = open(i, 'r').readlines()
            li.append(inp)
    count = 0
    lis = []
    for i in li:
        for j in i:
            for k in j[1:]          #ignore first entry in sublist
                if k == '/':
                    count += 1
                if count > 1:
                    lis.append(i[0][1:10])      
                    next_func(lis, outp)

谢谢,S :-)

4

3 回答 3

9

您的缩进可能是错误的,您应该count > 1for j in i循环内检查,而不是在检查j[1:].

此外,这里有一个更简单的方法来做同样的事情:

def count_slashes(items):
    return sum(item.count('/') for item in items)

for item in li:
    if count_slashes(item[1:]) > 1:
        print item[0][1:10]

或者,如果您需要列表中的 ID:

result = [item[0][1:10] for item in li if count_slashes(item[1:]) > 1]

Python列表推导生成器表达式是非常强大的工具,尝试学习如何使用它们,因为它让你的生活变得更加简单。上面的count_slashes函数使用了生成器表达式,而我的最后一个代码片段使用列表推导以一种简洁明了的方式构造了结果列表。

于 2010-06-04T12:17:03.067 回答
8

Tamás 提出了一个很好的解决方案,尽管它使用的编码风格与您完全不同。尽管如此,由于您的问题是“我在下面的一段代码中遇到了一些问题”,我认为还需要更多的东西。

以后如何避免这些问题

您在从“我想我知道如何编写此代码”到拥有实际工作代码的方法中犯了几个错误。

您为变量使用了无意义的名称,这使得几乎不可能理解您的代码,包括您自己。“但我知道每个变量的含义”的想法显然是错误的,否则您将设法自己解决这个问题。请注意,在我修复您的代码的地方,描述和讨论您的代码是多么困难。

你试图一次解决整个问题,而不是把它分解成碎片。编写一次只做一件事的小函数或代码片段。对于你工作的每一件作品,把它做好并测试它以确保它是正确的。然后继续写可能使用你已经得到的片段的其他片段。我说的是“碎片”,但通常这意味着函数、方法或类。

修复你的代码

这就是你所要求的,没有其他人这样做过。

您需要将该行移至该count = 0行之后for i in li:(适当缩进)。这将重置每个子列表的计数器。其次,一旦你附加lis并运行了你的next_func,你需要跳出for k in j[1:]循环和包含for j in i:循环。

这是一个工作代码示例(没有 next_func 但您可以将其添加到附加旁边):

>>> li = [['>0123456789 mouse gene 1\n', 'ATGTTGGGTT/CTTAGTTG\n', 'ATGGGGTTCCT/A\n'],   ['>9876543210 mouse gene 2\n', 'ATTTGGTTTCCT\n', 'ATTCAATTTTAAGGGGGGGG\n']]
>>> lis = []
>>> for i in li:
        count = 0
        for j in i:
            break_out = False
            for k in j[1:]:
                if k == '/':
                    count += 1
                if count > 1:
                    lis.append(i[0][1:10])
                    break_out = True
                    break
            if break_out:
                break

>>> lis
['012345678']

重新编写代码以使其可读

这样您就可以看到我在回答开头的意思。

>>> def count_slashes(gene):
    "count the number of '/' character in the DNA sequences of the gene."
    count = 0
    dna_sequences = gene[1:]
    for sequence in dna_sequences:
        count += sequence.count('/')
    return count
>>> def get_gene_name(gene):
    "get the name of the gene"
    gene_title_line = gene[0]
    gene_name = gene_title_line[1:10]
    return gene_name
>>> genes = [['>0123456789 mouse gene 1\n', 'ATGTTGGGTT/CTTAGTTG\n', 'ATGGGGTTCCT/A\n'],   ['>9876543210 mouse gene 2\n', 'ATTTGGTTTCCT\n', 'ATTCAATTTTAAGGGGGGGG\n']]
>>> results = []
>>> for gene in genes:
        if count_slashes(gene) > 1:
            results.append(get_gene_name(gene))

>>> results
['012345678']
>>> 
于 2010-06-04T13:16:48.700 回答
0
import itertools
import glob

lis = []
with open('output.txt', 'w') as outfile:
    for file in glob.iglob('*.ext'):
        content = open(file).read()
        if content.partition('\n')[2].count('/') > 1:
            lis.append(content[1:10])
            next_func(lis, outfile)

您对所有条目进行数字化的原因是因为您没有重置计数器。

于 2010-06-04T12:26:31.260 回答