Dar*_*ick 2 python counter loops
我在下面的代码中遇到了一些问题:
输入:li是嵌套列表,如下所示:
li = [['>0123456789 mouse gene 1\n', 'ATGTTGGGTT/CTTAGTTG\n', 'ATGGGGTTCCT/A\n'], ['>9876543210 mouse gene 2\n', 'ATTTGGTTTCCT\n', 'ATTCAATTTTAAGGGGGGGG\n']]
Run Code Online (Sandbox Code Playgroud)
使用下面的函数,我所需的输出只是'>'后的第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)
Run Code Online (Sandbox Code Playgroud)
谢谢,S :-)
您的缩进可能是错误的,您应该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]
Run Code Online (Sandbox Code Playgroud)
或者,如果您需要列表中的ID:
result = [item[0][1:10] for item in li if count_slashes(item[1:]) > 1]
Run Code Online (Sandbox Code Playgroud)
Python 列表推导和生成器表达式是非常强大的工具,尝试学习如何使用它们,因为它使您的生活更加简单.count_slashes
上面的函数使用生成器表达式,我的上一个代码片段使用列表推导以一种简洁的方式构造结果列表.
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']
Run Code Online (Sandbox Code Playgroud)
重新编写代码以使其可读
这样你就可以在我的回答开始时看到我的意思了.
>>> 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']
>>>
Run Code Online (Sandbox Code Playgroud)