PHPerがPython 2.7でタブ区切りファイル(TSV)を読み込んで処理した際のメモ
普段プログラミング言語はPHPを主に使用していますが、Python 2.7を使用する機会があったためメモを残します。
コマンドラインで実行する形式で行ったため、コマンドライン引数、引数に指定されたファイルの存在確認、ファイルを開く、読み取るなどの関数や処理をPHPなら~、Python 2.7なら~という形式でメモしています。
目次
- 目次
- コマンドライン引数
- ファイルの存在確認
- ファイルを開く
- 文字列を分割する
- 配列のスライス
- ファイルに書き込む
- 異なる型の値を含む配列/リストをjoinして出力
- コマンドライン引数に指定のTSVファイルを読み込み何かしら処理する例
コマンドライン引数
PHPもPython 2.7も始めの要素にはスクリプトパスが入っている。
PHP $argv
if ($argc < 2) { exit('引数が足りません。'); } print_r($argv);
Python 2.7 sys.argv
import sys if len(sys.argv) < 2: sys.exit('引数が足りません。') print sys.argv
ファイルの存在確認
PHP file_exists
if (!file_exists($argv[1])) { exit(sprintf('%s does not exist', $argv[1])); }
Python 2.7 os.path.exists
import sys import os.path if not os.path.exists(sys.argv[1]): sys.exit('%s does not exist' % sys.argv[1])
ファイルを開く
PHP fopen
や file_get_contents
を使うと思います。
fopen
$fh = fopen($filename, 'r'); fclose($fh);
- エラーハンドリングもする
$fh = fopen($filename, 'r'); if (!$fh) { exit($filename . 'を開けませんでした。'); } fclose($fh);
file_get_contents
$string = file_get_contents($filename);
Python 2.7 open
を使えますが、ファイルの読み込みなら with
構文をあわせて利用すると、ファイルの閉じ忘れがなくなり便利そうです。
with
構文を利用するopen
with open(filename, 'r') as fh:
with
構文を利用しない場合は使い終わった後に閉じます。
fh = open(filename, 'r') fh.close()
- エラーハンドリングもする
import sys fh = None try: fh = open(filename, 'r') except IOError as e: sys.exit('%sを開けませんでした。' % filename) fh.close()
文字列を分割する
タブで分割する場合。
PHPで \t
をタブとして用いる場合ダブルクォーテーションの必要がありますが、Pythonではシングルクォーテーションとダブルクォーテーションの区別がないようです。
PHP explode
$words = explode("\t", $row);
Python 2.7 split
words = row.split('\t')
配列のスライス
PHP array_slice
$row = ['a', 'b', 'c']; $words = array_slice($row, 0, -1); print_r($words); /* Array ( [0] => a [1] => b ) */
Python 2.7 スライス表記
というものがあるようです。
row = ['a', 'b', 'c'] words = row[:-1] print words # ['a', 'b']
ファイルに書き込む
PHP fwrite
fwrite($fh, '文字列');
Python 2.7 write
, writelines
fh.write('文字列');
words = ['文', '字', '列'] fh.writelines(words);
異なる型の値を含む配列/リストをjoinして出力
PHPだと型を気にせずに implode
で連結することが出来るところ、Python 2.7だと TypeError: sequence item 0: expected string, int found というエラーが発生して動作しなかったときの対処。
例えば id(int), name(string), created(string) というような配列/リストがあったとき、
PHP implode
$row = [123, 'name', date('Y-m-d H:i:s')]; print_r(implode("\t", $row)); // 123 name 2016-09-27 00:45:12
Python 2.7 join
import datetime row = [123, 'name', datetime.datetime.now()] print '\t'.join(row) # TypeError: sequence item 0: expected string, int found
Python 2.7でTypeError発生。
調べたところstringにconvertすると良い模様。
http://stackoverflow.com/questions/5618878/how-to-convert-list-to-string
import datetime row = [123, 'name', datetime.datetime.now()] print '\t'.join(str(col) for col in row) # 123 name 2016-09-27 00:45:12.804000
コマンドライン引数に指定のTSVファイルを読み込み何かしら処理する例
PHP fgetcsv
if ($argc != 2) { exit('1つ目の引数にはTSVファイルを指定してください。'); } if (!file_exists($argv[1])) { exit(sprintf('%s does not exist', $argv[1])); } if (($csvfile = fopen($argv[1], 'r')) !== false) { while (($columns = fgetcsv($csvfile, 0, "\t")) !== false) { // 何かしら処理 } fclose($csvfile); }
Python 2.7 csvモジュール
# coding: utf-8 import sys if len(sys.argv) != 2: sys.exit('1つ目の引数にはTSVファイルを指定してください。') import os.path if not os.path.exists(sys.argv[1]): sys.exit('%s does not exist' % sys.argv[1]) import csv with open(sys.argv[1], 'r') as csvfile: reader = csv.reader(csvfile, delimiter='\t') for columns in reader: # 何かしら処理