我在下面的代码中遇到了一些问题:
输入:li是嵌套列表,如下所示:
li = [['>0123456789 mouse gene 1\n', 'ATGTTGGGTT/CTTAGTTG\n', 'ATGGGGTTCCT/A\n'], ['>9876543210 mouse gene 2\n', 'ATTTGGTTTCCT\n', 'ATTCAATTTTAAGGGGGGGG\n']]
使用下面的功能,我想要的输出只是'>'后面的第2到第9位数字在整个子列表中存在的'/'的数量是> 1。
相反,我的代码给出了所有条目的数字。而且,它给了他们多次。因此,我认为我的计数器和我的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: - )
答案 0 :(得分:9)
您的缩进可能有误,您应该在count > 1
循环中检查for 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 list comprehensions和generator expressions是非常强大的工具,尝试学习如何使用它们,因为它会让您的生活变得更加简单。上面的count_slashes
函数使用生成器表达式,我的上一个代码片段使用列表推导以简洁的方式构造结果列表。
答案 1 :(得分: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']
>>>
答案 2 :(得分: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)
您对所有条目进行数字处理的原因是因为您没有重置计数器。