1

Python は初めてで、なぜこれが機能しないのか理解できません。テキスト ファイルに 1 行ずつ保存されている Web アドレスのリストがあります。最初の 10 個を bing という配列/リストに格納し、次の 10 個を yahoo というリストに格納し、最後の 10 個を Duckgo というリストに格納したいと考えています。関数を使用してreadlines、ファイルから各配列にデータを読み取ります。問題は、リストに何も書き込まれていないことです。カウントは正常に増加しています。また、ループを完全に削除して、テキスト ファイル全体を 1 つのリストに読み込むと、完全に機能します。これは、ループが問題を引き起こしていると私に信じさせます。私が使用しているコードは以下のとおりです。フィードバックをいただければ幸いです。

count=0;

#Open the file
fo=open("results.txt","r")

#read into each array
while(count<30):
    if(count<10):
        bing = fo.readlines()
        count+=1
        print bing
        print count

    elif(count>=10 and count<=19):
        yahoo = fo.readlines()
        count+=1
        print count

    elif(count>=20 and count<=29):
        duckgo = fo.readlines()
        count+=1
        print count

print bing
print yahoo
print duckgo

fo.close
4

4 に答える 4

5

readlinesファイルの読み取りに使用しています。一度にすべてreadlinesの行を読み取るため、最初のループでファイル全体を使い果たし、結果を. 次に、ループを通過するたびに、次の呼び出しの (空の) 結果で、、またはを上書きします。したがって、リストはすべて空になります。bingbingyahooduckgoreadlines

これを修正する方法はたくさんあります。とりわけ、readline(no 's') を使用して、一度に 1 行ずつファイルを読み取ることを検討する必要があります。forまたは、ループを使用するだけで、ファイルを 1 行ずつ反復処理することもできます。

for line in fo:
    ...

現在のコードの構造を維持するには、次を使用できますenumerate

for line_number, line in enumerate(fo):
    if condition(line_number):
        ...

しかし、率直に言って、現在のシステムを捨てるべきだと思います。はるかに簡単な方法はreadlines、ループなしで使用し、結果のリストをスライスすることです!

lines = fo.readlines()
bing = lines[0:10]
yahoo = lines[10:20]
duckgo = lines[20:30]

これを行うには他にも多くの方法があり、より良い方法もあるかもしれませんが、どれも簡単ではありません!

于 2012-06-20T00:09:55.697 に答える
1

次のように書き直すことをお勧めします。

bing = []
yahoo = []
duckgo = []
with open("results.txt", "r") as f:
    for i, line in enumerate(f):
        if i < 10:
            bing.append(line)
        elif i < 20:
            yahoo.append(line)
        elif i < 30:
            duckgo.append(line)
        else:
            raise RuntimeError, "too many lines in input file"

独自の変数を作成して自分でインクリメントする必要enumerate()はなく、実行中の行数を取得するためにどのように使用するかに注意してください。countこれはPythonでは良いスタイルと見なされています。

itertoolsしかし、この問題を解決する最善の方法は、次のように使用することだと思います。

import itertools as it
with open("results.txt", "r") as f:
    bing = list(it.islice(f, 10))
    yahoo = list(it.islice(f, 10)) 
    duckgo = list(it.islice(f, 10))
    if list(it.islice(f, 1)):
        raise RuntimeError, "too many lines in input file"

itertools.islice()(またはit.islice()私が行ったのでimport itertools as it)イテレータから指定された数のアイテムをプルします。開いているファイルハンドルオブジェクトfは、ファイルから行を返すイテレータであるためit.islice(f, 10)、入力ファイルから正確に10行をプルします。

it.islice()イテレータを返すため、listでラップして明示的にaに展開する必要がありますlist()

これが最も簡単な方法だと思います。それは私たちが望むものを完全に表現しています。それぞれについて、ファイルから10行のリストが必要です。カウンターをつける必要は全くなく、毎回10本引くだけ!

編集:余分な行のチェックはit.islice(f, 1)、1行だけをプルするように使用するようになりました。予想される30行以上あることを知るには、1行余分に追加するだけで十分です。このようにして、誰かが誤ってこのコードを非常に大きなファイルで実行した場合でも、ファイル全体をメモリに丸呑みしようとはしません。

于 2012-06-20T01:06:38.177 に答える
1

readlines()ファイルのすべての行を読み取ります。もう一度呼び出すと、空のリストが返されます。したがって、ループを反復処理するときにリストを空のデータで上書きしています。

于 2012-06-20T00:09:43.930 に答える
1

readline()代わりに使用する必要がありますreadlines()

readlines()ファイル全体を一度にreadline()読み取りますが、ファイルから 1 行を読み取ります。

于 2012-06-20T00:11:04.533 に答える