words = line.split('\n')
num_words += len(words)
は、あなたはそれがないと思う何をしません。ループ内
for line in f:
line
は'\n'
で終了する文字列であるので、line.split('\n')
が終了'\n'
別にラインのすべての文字を含む最初の項目で、二項目のリストです。そのリストの2番目の項目は空の文字列です。例:
line = 'This is a test\n'
words = line.split('\n')
print(words, len(words))
出力
['This is a test', ''] 2
だからあなたnum_words += len(words)
が実際に単語をカウントしない、それだけで行数の二倍のカウントを取得します。
はあなたが必要
line
中の単語の実際のリストを取得するには
words = line.split()
それが最後の行のスペース数を減算してあなたの最後から二番目のライン
num_charsx = num_chars - line.count(' ')
はfor
ループの外にありますファイル全体のnum_chars
から、しかし私はあなたが実際にファイル全体の合計のスペース数をnum_chars
から差し引きたいと仮定します。
修正されたバージョンのコードです。
num_words = 0
num_chars = 0
num_spaces = 0
with open(fname, 'r') as f:
for num_lines, line in enumerate(f, 1):
num_words += len(line.split())
num_chars += len(line) - 1
num_spaces += line.count(' ')
num_charsx = num_chars - num_spaces
print(num_lines, num_words, num_chars, num_spaces, num_charsx)
enumerate
を使用するようにライン読み取りループを変更しました。これは、行番号と行の内容を個別の行カウンタを維持することなく取得する効率的な方法です。
num_chars += len(line) - 1
-1
では、各行の末尾にはが含まれていません。
Windowsでは、テキストファイルの行は(通常)'\r\n'
で終端されていますが、テキストモードで開いたファイルを読み取ると、ターミネーターは'\n'
に変換されます。したがって、Windowsではファイルの実際のバイトサイズはnum_chars + 2 * num_lines
です。最後の行に'\r\n'
ターミネータがあると仮定します。実際のサイズは2バイト小さくなります。