0

次のようなテキスト ファイルがあります。

BALLOTS CAST
Riding 0
YES YES NO YES
NO NO NO NO 
.
.
.
YES NO YES YES

Riding 1
YES NO NO YES
NO NO YES NO 
.
.
.
YES YES YES YES

等々。という名前の乗車番号に対するユーザーの入力があり、ridingその乗車に対する投票のリストを作成する必要があります。たとえば、乗馬の選択肢が 0 の場合、 list が必要[[YES YES NO YES], [NO NO NO NO], ..., [YES NO YES YES]]です。

readline()使用方法とwhileループを理解する必要があります。ここに私が持っているものがあります:

ballots = open(FILENAME, 'r')
line = ballots.readline().rstrip()
L = []
i = 0
if riding.isdigit():
    while i < ???:
        line = ballots.readline().rstrip()
        i += 1
        if line == 'Riding ' + riding:
            while line != '\n':
                L.append(line.rstrip().split())

しかし、私は空のリストを取得します。180代わりにこれを試してみまし???たが、それは何行あるのかという理由ですが、実際に何をその場所に置くべきかわかりません。試してみmax(enumerate(ballots))[0]ましたが、リストが完全に空になりますballots(または、何らかの理由ですべてが空になります)。

誰でも私のエラーと何を変更すべきかを指摘できますか? 私が言ったように、私はreadline()andを使用する必要がありwhile、何もインポートできません。

また、付けた理由は、乗り物if riding.isdigit()を選択するオプションもあるためです。allできます:

if riding == 'all':
    line = ballots.readline().rstrip()
    for line in ballots:
        if line[0:6] != 'Riding' and line != '\n':
            L.append(line.rstrip().split())

while唯一の問題は、ループの代わりにループを使用する方法がわからないことforです...

4

3 に答える 3

3

Pickle を見てみましょう: http://docs.python.org/2.7/library/pickle.html?highlight=pickle#pickle Python オブジェクトをリストなどのファイルに保存および復元するのに非常に便利です。

于 2012-11-28T09:28:07.143 に答える
2

状態変数を使用して、いつ行を読み取る必要があるかを検出する必要がありbreakます。ループが終了したときは次のようになります。

lines = []
with open(FILENAME, 'r') as ballots:
    foundriding = False
    ballots.next()  # skip first line
    for line in ballots:
        if line.rstrip() == 'Riding ' + riding:
            foundriding = True
            continue
        if not foundriding: 
            continue
        line = line.rstrip()
        if line and not line.startswith('Riding '):
            lines.append(line)
        else:
            break

上記のコードは、正しい行が見つかるまですべての行をスキップしRiding <number>、その時点でfoundridingTrue に設定されます。linesフラグが設定されると、空の行または で始まる別の行が見つかるまで、後続のすべての行が に追加されますRiding。その時点で、読み取りループが中断されます。

別の代替手段は、次を使用することitertools.takewhile()です。

from itertools import takewhile
with open(FILENAME, 'r') as ballots:
    ballots.next()  # skip first line
    for line in takewhile(lambda l: l.rstrip() != 'Riding ' + riding, ballots):
        pass  # skip lines
    lines = [l.rstrip() for l in takewhile(lambda l: l.rstrip() and not l.startswith('Riding '), ballots)]

takewhileテストが False を返すまで、投票から行を取得します。その後、別のテストでさらに行を取得できます。つまり、行が空ではなく、で始まらないことRidingです。

どちらのソリューションも、ファイル全体を読み取る必要はありません。正しいライディングが見つかり、すべての投票が に読み込まれると、読み取りを停止しlinesます。

ballotsファイル オブジェクトをイテレータのように使用します。.readline()これは;とまったく同じ方法ではありません。.readline()厳しい要件 (うーん、教師と宿題) の場合は、イテレータにすることもできますballot.readline()

ballotiterator = iter(ballots.readline, '')

次に、表示される場所ballotiteratorの代わりに、またはを使用します。ballotsfor line in ballotsballots.next()takewhile(..., ballots)

于 2012-11-28T07:57:52.910 に答える
1

正規表現を使用した別のソリューション:

import re
with open("test.txt") as infile:
    text = infile.read()
    if riding.isdigit():
        section = re.search(r"(?sm)^Riding " + riding + r".*?(?=Riding|\Z)", text)
        matches = re.findall(r"(?:(?:YES|NO) ?)+", section.group(0))
        result = [s.split() for s in matches]
        print(result)

riding設定すると"1"、次のようになります。

[['YES', 'NO', 'NO', 'YES'], ['NO', 'NO', 'YES', 'NO'], ['YES', 'YES', 'YES', 'YES']]

もちろん、あなたは使いたいかもしれません

result = [[True if value == "YES" else False for value in s.split()] 
                                             for s in matches]

代わりに、取得するために

[[True, False, False, True], [False, False, True, False], [True, True, True, True]]

エラーチェックは行われませんが (たとえば、ラベル付けされたセグメントRiding xが入力ファイルに存在するかどうかなど)、簡単に追加できます。

于 2012-11-28T08:03:20.680 に答える