4

私はテキスト ファイルを持っており、1 行おきにテキストのチャンクを抽出する必要がある条件を設定していますが、テキストのチャンクは任意の行数にすることができます (バイオインフォマティクス関係者向けの FASTA ファイル)。基本的には次のように設定されています。

> header, info, info
TEXT-------------------------------------------------------
----------------------------------------------------
>header, info...
TEXT-----------------------------------------------------

...など。

「TEXT」部分を抽出しようとしています。設定したコードは次のとおりです。

for line in ffile:
    if line.startswith('>'):

      # do stuff to header line

        try:
            sequence = ""
            seqcheck = ffile.next() # line after the header will always be the beginning of TEXT
            while not seqcheck.startswith('>'):
                        sequence += seqcheck
                        seqcheck = ffile.next()

        except:       # iteration error check
            break

next() を呼び出すたびに for ループが続行され、多くの行がスキップされ、多くのデータが失われるため、これは機能しません。イテレータを前に移動せずに、次の行を「覗く」にはどうすればよいですか?

4

5 に答える 5

0

覗くための私の推奨は、リストとを使用することですenumerate:

lines = ffile.readlines()
for i, line in enumerate(lines):
    if line.startswith('>'):
        sequence = ""
        for l in lines[i+1:]:
            if l.startswith('>'):
                break
            sequence += l
于 2014-06-04T19:52:18.360 に答える
0

元のコードをほとんど変更しない方法を次に示します。状況にもよりますが、他のすべてを再編成/リファクタリングすることを心配する必要がなく、やりたいことだけを行う方が簡単な場合があります! 何かを押し戻したい場合は、それができるようにしてください。

ここでは、以前に読み取った行を保持する deque() オブジェクトをインスタンス化します。次に、オブジェクトの単純なチェックを行い、ffile から新しい行を取得する前にエントリを排出する ffile イテレータをラップします。

したがって、どこかで再処理が必要なものを読み取るたびに、それを deque オブジェクトに追加してブレークアウトします。

import cStringIO,collections
original_ffile=cStringIO.StringIO('''
> header, info, info
TEXT----------------------------------------------------------------
TEXT2-------------------------------------------
>header, info...
TEXT-----------------------------------------------------''')

def peaker(_iter,_buffer):
    popleft=_buffer.popleft
    while True:
        while _buffer: yield popleft() # this implements FIFO-style
        yield next(_iter) # we don't have to catch StopIteration here!
buf=collections.deque()
push_back=buf.append
ffile=peaker(original_ffile,buf)
for line in ffile:
    if line.startswith('>'):
        print "found a header! %s"%line[:-1]
        # do stuff to header line
        sequence = ""
        for seqcheck in ffile:
            if seqcheck.startswith('>'):
                print "oops, we've gone too far, pushing back: %s"%seqcheck[:-1]
                push_back(seqcheck)
                break
            sequence += seqcheck

出力:

found a header! > header, info, info
oops, we've gone too far, pushing back: >header, info...
found a header! >header, info...
于 2015-07-16T02:14:03.660 に答える