2

次の形式のデータがあります。

data = """

[Data-0]
Data = BATCH
BatProtocol = DIAG-ST
BatCreate = 20010724

[Data-1]
Data = SAMP
SampNum = 357
SampLane = 1

[Data-2]
Data = SAMP
SampNum = 357
SampLane = 2

[Data-9]
Data = BATCH
BatProtocol = VCA
BatCreate = 20010725

[Data-10]
Data = SAMP
SampNum = 359
SampLane = 1

[Data-11]
Data = SAMP
SampNum = 359
SampLane = 2

"""

構造は次のとおりです。

  1. [Data-x]ここで、x は数値です
  2. Data =BATCHまたは_SAMPLE
  3. さらにいくつかの行

「バッチ」ごとにリストを生成する関数を作成しようとしています。リストの最初の項目は行を含むテキストブロックData = BATCHで、リストの次の項目は行を含むテキストブロックData = SAMPです。私は現在持っています

def get_batches(data):
    textblocks = iter([txt for txt in data.split('\n\n') if txt.strip()])
    batch = []
    sample = next(textblocks)
    while True:
        if 'BATCH' in sample:
            batch.append(sample)
        sample = next(textblocks)
        if 'BATCH' in sample:
            yield batch
            batch = []
        else:
            batch.append(sample)

このように呼び出された場合:

batches = get_batches(data)
for batch in batches:
    print batch
    print '_' * 20

ただし、最初の「バッチ」のみを返します。

['[Data-0]\nData = BATCH\nBatProtocol = DIAG-ST\nBatCreate = 20010724', 
 '[Data-1]\nData = SAMP\nSampNum = 357\nSampLane = 1', 
 '[Data-2]\nData = SAMP\nSampNum = 357\nSampLane = 2']
____________________

一方、私の予想される出力は次のようになります。

['[Data-0]\nData = BATCH\nBatProtocol = DIAG-ST\nBatCreate = 20010724', 
 '[Data-1]\nData = SAMP\nSampNum = 357\nSampLane = 1', 
 '[Data-2]\nData = SAMP\nSampNum = 357\nSampLane = 2']
____________________
['[Data-9]\nData = BATCH\nBatProtocol = VCA\nBatCreate = 20010725', 
 '[Data-10]\nData = SAMP\nSampNum = 359\nSampLane = 1', 
 '[Data-11]\nData = SAMP\nSampNum = 359\nSampLane = 2']
____________________

不足しているもの、または機能を改善するにはどうすればよいですか?

4

2 に答える 2

6

次のバッチの始まりを見つけたときにのみバッチを生成するため、データの最後のバッチを含めることはありません。これを修正するには、関数の最後に次のようなものが必要です。

if batch:
    yield batch

ただし、これを行うだけでは機能しません。最終的にループのnext(textblocks)内側で a が発生するStopIterationため、ループの後のコードはwhile実行できません。現在のコードを少し変更するだけで、これを機能させる 1 つの方法を次に示します (より良いバージョンについては、以下を参照してください)。

def get_batches(data):
    textblocks = iter([txt for txt in data.split('\n\n') if txt.strip()])
    batch = []
    sample = next(textblocks)
    while True:
        if 'BATCH' in sample:
            batch.append(sample)
        try:
            sample = next(textblocks)
        except StopIteration:
            break
        if 'BATCH' in sample:
            yield batch
            batch = []
        else:
            batch.append(sample)
    if batch:
        yield batch

textblocks代わりにループでループすることをお勧めしforます:

def get_batches(data):
    textblocks = (txt for txt in data.split('\n\n') if txt.strip())
    batch = []
    for sample in textblocks:
        if 'BATCH' in sample:
            if batch:
                yield batch
            batch = []
        batch.append(sample)
    if batch:
        yield batch
于 2013-04-09T19:34:17.243 に答える