12. イテレータ¶
mcmdでは行単位およびキー単位のイテレータが用意されている。 既存のmcmdメソッドを組み合わせるだけでは困難な処理があった場合に利用でき、 行単位もしくはキーブロック単位で処理するPythonコードを書くことができる。 表 表 12.1 にmcmdが提供するイテレータの一覧を示している。
表 12.1 処理フローオブジェクトで利用できるメンバーメソッド一覧¶ メソッド名: 内容
パラメータ
なし
dtype
={項目名:str|int|float|bool,...}
otype
="list" | "dict"
skeys
=項目名リスト,
keys
=項目名リスト
header
=True|False
q
=True|False
dtype
={項目名:str|int|float|bool,...}
otype
="list" | "dict"
skeys
=項目名リスト,
keys
=項目名リスト
header
=True|False
q
=True|False
12.1. __iter__: 行イテレータ¶
処理フローオブジェクトにはイテレータメソッド(__iter__)が定義されており、
行単位にリストに出力する繰り返し処理を可能としている。
リスト 12.1 は、for-in 文を使って一行づつ出力している例である。
すべての値は文字列として出力されることに注意されたい。
これは、mcmdが内部ではデータをすべてテキストのバイトストリームとして処理しているためである。
項目別に型を指定するのであれば、getline
メソッドを使えば良い。
また、先頭の項目名行は出力されないのは仕様であり、これも getline
を使えば出力できる。
1import nysol.mcmd as nm 2dat=[ 3["customer","date","amount"], 4["A","20180101",5200], 5["B","20180101",800], 6["B","20180112",3500], 7["A","20180105",2000], 8["B","20180107",4000] 9] 10for line in nm.mcut(f="customer,date,amount",i=dat): 11 print(line)
12.2. getline: 出力形式指定行イテレータ¶
getline
メソッドは、出力形式を制御できるイテレータである。
otype="dict"
を指定することで、リストではなく項目名をキーとする辞書型で出力することが可能で、
header=True
でヘッダー行を出力することが可能となる。
dtype
パラメータによって出力項目の型を指定し、otype
によってコンテナ型としてリストもしくは辞書を指定できる。
dtype
を指定しなければ、全ての項目は文字列として出力され、otype
を指定しなければリストで出力される。
また skeys
で項目名を指定すると、事前に指定した項目でソーティングできる。
さらに keys
の指定によりキーブレイク情報も出力可能となる。
パラメータ |
内容 |
---|---|
dtype={項目名:型,...}
optional
default:全項目"str"型
|
辞書型データで指定し、キーに項目名、値にデータ型を指定する。
変換可能なデータ型は次の通り。
"str":文字列, "int":整数, "float":実数, "bool":真偽値
例) dtype={"customer":"str","date":"str","amount":"int"}
|
otype=型
optional
default:"list"
|
出力データのコンテナ型を指定する。
"list"(リスト型),"dict"(辞書型)の2つの型を指定できる。
"list"を指定した場合、項目名ヘッダーは出力されない。
"dict"を指定した場合、辞書のキーが項目名で、値がその項目の値となる。
例) otype="dict"
|
skeys=項目名リスト
optional
default:sortingなし
|
事前にソーティングを行う。そのソーティングキーを指定する。
例) skeys="amount%nr,customer" #
amount 項目数値降順+ customer 項目昇順 |
keys=項目名リスト
optional
default:キーブレイク情報の出力なし
|
指定された項目名リストに従ったキーブレイク情報も出力する。
出力されるデータ形式はタプルで、([行データ],top,bottom)となる。
例) keys="customer,date"
|
header=True|False
optional
default:False
|
ヘッダー行も出力する。
|
q=True|False
optional
default:False
|
k= 項目で事前にソートしない。 |
リスト 12.3 は、リスト 12.1 と同様の処理を項目名ヘッダーの出力を加えた処理になっている。
1f=nm.mcut(f="customer,date,amount",i=dat).getline(header=True) 2for line in f: 3 print(line) 4# 以下、出力内容 5# ['customer', 'date', 'amount'] 6# ['A', '20180101', '5200'] 7# ['B', '20180101', '800'] 8# ['B', '20180112', '3500'] 9# ['A', '20180105', '2000'] 10# ['B', '20180107', '4000']
リスト 12.4 は、 リスト 12.1 と同様のデータについて、amount
のみを整数(int
)で出力し、
コンテナとして辞書型(dict
) を指定している。
1dtype = {'customer':'str', 'date':'str', 'amount':'int'} 2f=nm.mcut(f="customer,date,amount",i=dat).getline(dtype=dtype,otype="dict") 3for line in f: 4 print(line) 5# {'customer': 'A', 'date': '20180101', 'amount': 5200} 6# {'customer': 'B', 'date': '20180101', 'amount': 800} 7# {'customer': 'B', 'date': '20180112', 'amount': 3500} 8# {'customer': 'A', 'date': '20180105', 'amount': 2000} 9# {'customer': 'B', 'date': '20180107', 'amount': 4000}
リスト 12.5 は、リスト 12.4 に加えて、amount
で数値降順に並べ替えた後に繰り返し処理を行っている。
数値降順にするためには、項目名の後ろに %nr
を付ける必要があるが、
これは msortf の f=
の指定方法と同様の規則に従っている。
なお、dtype
での型指定と skeys
で指定するソーティングの型指定は、内部的には全く独立に動作する。
例えば、 skeys="amount%nr",dtype={"amount":"str"}
としていても、並び順は数値降順( %nr
)であり、
出力される amount
項目は文字列( "str"
)となる。
1f=nm.mcut(f="customer,date,amount",i=dat).getline(dtype=dtype,otype="dict",skeys="amount%nr") 2for line in f: 3 print(line) 4# {'customer': 'A', 'date': '20180101', 'amount': 5200} 5# {'customer': 'B', 'date': '20180107', 'amount': 4000} 6# {'customer': 'B', 'date': '20180112', 'amount': 3500} 7# {'customer': 'A', 'date': '20180105', 'amount': 2000} 8# {'customer': 'B', 'date': '20180101', 'amount': 800}
リスト 12.6 は、customer
項目で並べ替えた時のキーブレイク情報を出力に付加する。
出力形式は、コンテナはタップルで、([行データリスト],先頭行フラグ,最終行フラグ)である。
先頭行フラグは、同じキー値の先頭行を読み込んでいるときのみ True
となるBool値である。
最終行フラグは、同様に同じキー値の最終行を読み込んでいるときのみ False
となるBool値である。
なお、同じキー内での並び順は、skeys
パラメータを用いれば良い。
リスト 12.6 では、 skeys="amount%nr"
と指定しており、
結果として、customer
昇順+ amount
数値降順で出力される。
1f=nm.mcut(f="customer,date,amount",i=dat).getline(keys="customer",skeys="amount%nr") 2for line in f: 3 print(line)リスト 12.7 リスト 12.6 の実行結果。例えば、最初の行は、キー項目値A
の先頭行であるためタップル二番目の要素がTrue
になっており、最終行はキー項目B
の最終行なのでタップル三番目の要素がTrue
となっている。¶(['A', '20180101', '5200'], True, False) (['A', '20180105', '2000'], False, True) (['B', '20180101', '800'], True, False) (['B', '20180107', '4000'], False, False) (['B', '20180112', '3500'], False, True)
12.3. keyblock: キー単位のイテレータ¶
getline
メソッドが行単位で繰り返し処理をする一方で、keyblock
メソッドでは、キーブロック(キー項目の値が同じ行)を単位として繰り返し処理を行う。
よって、データは2重リストもしくは辞書inリストの形式で得られることになる。
指定可能なパラメータは getline
メソッドと同様であるが、keys
の指定は必須である。
パラメータ |
内容 |
---|---|
keys=項目名リスト
必須
|
キーブロックとなる項目を指定する。
出力されるデータ形式は二重リスト(もしくはdict要素のリスト)で、
([[行データ1],[行データ2],...,[行データn])となる(nはブロックに含まれる行数)。
例) keys="customer"
|
skeys=項目名リスト
optional
default:sortingなし
|
キーブロック内でのソーティング項目を指定する。
例) skeys="amount%n" #
amount 項目数値昇順 |
dtype={項目名:型,...}
optional
default:全項目"str"型
|
辞書型データで指定し、キーに項目名、値にデータ型を指定する。
変換可能なデータ型は次の通り。
"str":文字列, "int":整数, "float":実数, "bool":真偽値
例) dtype={"customer":"str","date":"str","amount":"int"}
|
otype=型
optional
default:"list"
|
出力データのコンテナ型を指定する。
"list"(リスト型),"dict"(辞書型)の2つの型を指定できる。
"list"を指定した場合、項目名ヘッダーは出力されない。
"dict"を指定した場合、辞書のキーが項目名で、値がその項目の値となる。
例) otype="dict"
|
header=True|False
optional
default:False
|
ヘッダー行も出力する。
|
q=True|False
optional
default:False
|
k= 項目で事前にソートしない。 |
リスト 12.8 は、リスト 12.1 と同様のデータについて、customer
をキーブロック項目に指定した例である。
出力結果を見てもわかるように、customer
項目の値ごとに繰り返し処理が行われており、行とブロックの二重リストでデータが得られる。
また、このケースでは skeys="date"
と指定しているので、customer
の中では日付順に並んでいる。
1dtype = {'customer':'str', 'date':'str', 'amount':'int'} 2f=nm.mcut(f="customer,date,amount",i=dat).keyblock(keys="customer",skeys="date",dtype=dtype): 3for line in f: 4 print(line) 5# [['A', '20180101', 5200], ['A', '20180105', 2000]] 6# [['B', '20180101', 800], ['B', '20180107', 4000], ['B', '20180112', 3500]]
header=True
を付けた場合は、最初に項目名ヘッダー行がブロックとして二重リストで出力される( リスト 12.9 )。
1dtype = {'customer':'str', 'date':'str', 'amount':'int'} 2f=nm.mcut(f="customer,date,amount",i=dat).keyblock(header=True,keys="customer",skeys="date",dtype=dtype): 3for line in f: 4 print(line) 5# [['customer', 'date', 'amount']] 6# [['A', '20180101', 5200], ['A', '20180105', 2000]] 7# [['B', '20180101', 800], ['B', '20180107', 4000], ['B', '20180112', 3500]]
dtype
, otype
の指定方法は getline
メソッドと同様である。
リスト 12.10 は、リスト 12.8 の例を辞書型で出力した例である。
1dtype = {'customer':'str', 'date':'str', 'amount':'int'} 2f=nm.mcut(f="customer,date,amount",i=dat).keyblock(keys="customer",skeys="date",dtype=dtype,otype="dict"): 3for line in f: 4 print(line) 5# [{'customer': 'A', 'date': '20180101', 'amount': 5200},{'customer': 'A', 'date': '20180105', 'amount': 2000}] 6# [{'customer': 'B', 'date': '20180101', 'amount': 800},{'customer': 'B', 'date': '20180107', 'amount': 4000},{'customer': 'B', 'date': '20180112', 'amount': 3500}]
同じキーの行数が膨大なデータに対して keyblock
を利用する場合は注意が必要である。
keyblock
メソッドは、メモリが許す限り、ブロック内のデータをpythonのリスト上に展開しようと試みるが、
メモリ制限を超えた場合の動作は不定である。