我有一个大型的表格格式爆炸文件,目标序列的数量不受限制,因此解析需要很长时间。我想将每个查询序列的点击数减少到前10个。
我的python很基本,但是到目前为止

import sys

blastfile = open(sys.argv[1],"r")

column1list=[]

for line in blastfile:
    b = line.split()[0]
    column1list.append(b)

uniqcolumn1 = list(set(column1list))

counter = 0

for val in uniqcolumn1:
    #print val
    for line in blastfile:
        #print line
        while counter <= 10:
            if line.startswith(val):
                print line
                counter =+ 1


这是爆炸输出文件的一行示例,查询序列的标题在第一列中,在这种情况下为'c8208_g1_i2'

c8208_g1_i2 gi|851252702|ref|WP_048131971.1|    79.30   797 165 0   4881    2491    1   797 0.0 1336    acetyl-CoA decarbonylase/synthase complex subunit alpha [Methanosaeta concilii]


我认为代码的第一部分工作正常,直到“
uniqcolumn1 = list(set(column1list))',那么我无法从列表中的每个字符串开始打印前十行。

最佳答案

这里的问题似乎是您要遍历文件对象两次。在Python中,文件对象的工作方式很像读取每一行的指针。如果不将指针移回,则没有任何内容可读取。

您需要做的是使用.seek函数将此指针移回起点。例如,假设您有一个file_to_read.txtpython_script.py

file_to_read.txt

Hello! My name is Bob and I can't think of anything to
put in this file so I'm blabbering on about nonsense
in hopes that you won't realise that this text is not
important but the code in the actually file, though I
think that you wouldn't mind reading this long file.


python_script.py

f = open("file_to_read.txt", "r")
for line in f: print line
for line in f: print line


如果要运行此代码(并且不会发生有关目录的错误),则只需将file_to_read.txt打印一次。为了解决这个问题,您可以在阅读之间添加一个f.seek(0, 0)。例如:

f = open("file_to_read.txt", "r")
for line in f: print line
f.seek(0, 0)
for lien in f: print line


现在,回到您的上下文,您可以看到它如何应用于您的代码:

import sys
# Here is your reading of file
blastfile = open(sys.argv[1],"r")
column1list = []
# Here is the first time you read the file
for line in blastfile:
    b = line.split()[0]
    column1list.append(b)
# Add a line to move back to the start before the
# next reading
blastfile.seek(0, 0)

uniqcolumn1 = list(set(column1list))

for val in uniqcolumn1:
    # Move the counter inside to refresh it after every iteration
    counter = 0
    # Here is the second time you read your file
    for line in blastfile:
        while counter <= 10:
            if line.startswith(val):
                print line
                counter += 1
    # Since you are going to read the file the next iteration,
    # .seek the file
    blastfile.seek(0, 0)


编辑

这是固定的代码后半部分。您可以执行以下任一操作:

for val in uniqcolumn1:
    # Move the counter in
    counter = 0
    # Move the while loop out
    while counter <= 10:
        for line in blastfile:
            if line.startswith(val):
                print line,
                counter += 1
    blastfile.seek(0, 0)


这样做的好处是for循环较早终止,它不会读取整个文件。

另一种方法是使用此方法:

for val in uniqcolumn1:
    # Move counter in
    counter = 0
    # Remove while statement
    for line in blastfile:
        # Add additional condition to if statement
        if line.startswith(val) and counter <= 10:
            print line,
            counter += 1
        elif counter > 10:
            break
    blastfile.seek(0, 0)


这样做的好处是看起来更简单。

08-25 08:47
查看更多