[Home]
[Setting up Mac OS X]
[Python]:
ファイルを読む
[日本語を使う]
Python Tutorial にあまり書かれていなかった、「ファイルの読み方」について、例を示します。
質問やプロンプトを出して、一行ずつ答えを端末から読む場合は、 raw_input() を使う次の方法が簡単です。
name = raw_input('Enter name: ')
print name
標準入力から読むには、sys をimport しておき、sys.stdin を用います。 次の例は、1行ずつ、標準入力から読んで標準出力に書き出します。 (なお、print 文が自分で改行を付け足さないよう、最後にコンマがついています。)
#!/usr/bin/env python
import sys
for line in sys.stdin:
print line,
*注意:Unixの場合、改行コードはLF (\n)です。他のシステムで作ったファイルを処理する場合は、 あらかじめ、改行コードを置き換えておきます。
ファイルを開いて読む方法は Tutorial の9.9 Iteratorsにも書かれていますが、念のため。
#!/usr/bin/env python
for line in open('text.txt', 'r'):
print line
上の例は、ファイルを閉じるのはPythonのgarbage collectorにお任せですが、 自分でファイルを閉じたい場合は、次のようにします。(日下氏の説明)
#!/usr/bin/env python
f = open('text.txt', 'r')
for line in f:
print line,
f.close()
タブで区切られたファイルを読んで、タブで各行の中身を切り分けるには、 split('\t')を用います。次の例は、区切った文字列を、リストとして書き出しています。
#!/usr/bin/env python
for line in open('text.txt', 'r'):
itemList = line[:-1].split('\t')
print itemList
for item in itemList:
print item+'/',
print ''
(name, zip, address) = tuple( itemList )
#!/usr/bin/env python
for line in open('text.txt', 'r'):
name, zip, address = line[:-1].split('\t')
print name, zip, address
Pythonで読み込まれたものは、「文字列」の型を持っています。したがって、 ファイルに '123'と書かれたものをlineという変数に読み込んでも、これは '123'という文字列ですので、line + 5 などという計算はできません。 (ちなみに、line * 5 とやると、文字列を5回繰り返して'123123123123123'ができます。) Cなどのように、「読み込む際に」%d などを使って型を指定はせず、 文字列として「読み込んだ後」に型の変換をします。
次の例は、各行に整数、タブ、実数 という形で書かれた次のようなファイルを読み込み、それらの積をプリントします。
10 2.5 30 4.9
#!/usr/bin/env python
for line in open('text.txt', 'r'):
items = line.split('\t')
print items, int(items[0]) * float(items[1])
numbers = [int(items[0]), float(items[1])]
print numbers
各行に、タブで区切られた整数が一杯書かれたファイルを読み、各行ごとに「数」のリストを作る一つの方法は、次のようなものです。
#!/usr/bin/env python
for line in open('numbers.dat'):
itemList = line.split('\t')
numbers = []
for item in itemList:
numbers.append( int(item) )
print numbers
itemを一つずつ型変換してリストに足していくのが面倒だという人には、 list comprehension という方法が便利です。(かつ、直感的?)
#!/usr/bin/env python
for line in open('numbers.dat'):
itemList = line.split('\t')
numbers = [ int(item) for item in itemList ]
print numbers
中2行を次のようにまとめることも可。
numbers = [ int(item) for item in line.split('\t') ]
また、map を使う方法もあります。(日下氏より)
numbers = map(int, line.split('\t'))
numpyを使う方法もあります。
import numpy as np
table = np.loadtxt('numbers.dat')
行と列を入れ替えるには(転置するには)
table = np.loadtxt('numbers.dat').T
ファイルを一行ずつではなく、全部読み込んで処理することもできます。 次の例は、HTMLファイルの <BODY> ... </BODY> ではさまれた 部分を取り出します。
allLines = open('foo.html').read()
head, body = allLines.split('<BODY>')
meat, tail = body.split('</BODY>')
Python 2.4以降、日本語なども標準的なパッケージで扱えるようになりました。 これにより、shift_jis, euc_jp, iso2022-jp, utf_8などの文字コードで書かれた ファイルの読み書きや、 日本語の文字の入った文字列の処理などができます。
例えば、dirctory内の *.txt のファイルを全て選んで、一つずつ読むには、 Tutorialにも書かれているように、次にようにするのが楽です。
#!/usr/bin/env python
import glob
for file in glob.glob('*.txt'):
print file, '-'*20
for line in open(file, 'r'):
print line,
print glob.glob('*.txt')
とすれば、リストとしてプリントされます。
#!/usr/bin/env python
import os
for file in os.popen('ls *.txt').read().split():
print file, '-'*20
Updated 2017-06-29, Taku Yamanaka