文字列の分割・検索・置換
商品名・個数・単価を含む一行を分割し、空白除去と数値変換を行います。検索位置、置換、結合、表示桁数を確認し、加工前の値がどう残るか比較します。
説明
文字列の加工は元の文字列を書き換えるのではなく、新しい文字列を返します。区切りや空白をどこまで意味のあるデータとして残すかを決めてから加工します。
商品名・個数・単価を含む一行を分割し、空白除去と数値変換を行います。検索位置、置換、結合、表示桁数を確認し、加工前の値がどう残るか比較します。
1一行を区切る
今回は引用符や項目内のカンマを含まない単純な区切り行です。両端と各項目に空白を入れています。
raw = " pen , 03 , 120.5 "加工前の一行; parts = raw.split(",")カンマで分割; print(repr(raw), parts)空白を含めて比較カンマで三つに分かれますが、項目の空白は残ります。splitは引用符の規則を解釈するCSV解析ではないので、この操作は今回の単純な入力条件に限定しています。
2各項目の両端だけを整える
stripで各項目の両端の空白を除き、三つの名前へ取り出します。
item, quantity_text, price_text = [part.strip() for part in parts]各項目の両端を処理; print(item, quantity_text, price_text)取り出した三項目; print(repr(raw))元の文字列は維持pen、03、120.5になり、rawは空白を含む元のままです。stripは内側の空白を一律に消す操作ではありません。
3明示した区切りは空項目を残す
空白分割と明示した区切りで、連続する区切りの扱いを比較します。
print("a b".split(), "a b".split(" ")空白類の分割と明示区切り); print("pen,,120.5".split(",")空の個数項目); print("note=blue=pen".split("=", 1)分割回数を制限)引数なしのsplitは連続する空白をまとめます。区切り文字として空白やカンマを明示すると、空の項目も残します。maxsplit=1では最初の一回だけ分割し、残りの=を値に含めます。空の項目を残すかどうかは、データ形式に合わせて決めます。
4検索位置0と未検出-1
商品名のpenと、存在しない文字列をfindで探します。
print(item.find("pen"), item.find("missing")一致位置と未検出); print("pen" in item, "missing" in item含まれるかを真偽で判定)先頭の一致は0、未検出は-1です。if item.find(...)のように数値をそのまま真偽へ使うと、先頭一致0を偽、未検出-1を真として扱ってしまいます。所属だけが必要ならinを使えます。
5部分文字列の置換と元の値
penを置き換え、pencilにも同じ部分文字列が含まれることを確認します。
renamed = item.replace("pen", "marker")置換結果を別名へ保持; print(item, renamed, "pencil".replace("pen", "marker"))元の値と部分置換; print(",".join([renamed, quantity_text, price_text]))三項目をカンマで結合元のitemはpenのまま、renamedはmarkerです。pencilもmarkercilへ変わるため、replaceは単語や商品コードの一致を保証しません。joinは一覧の間へ区切りを入れて新しい一行を作ります。
6stripの引数は接尾辞ではない
ファイル名の末尾.csvを取り除きたい場面で、stripとremovesuffixを比較します。
name = "civic.csv"末尾と本体に同じ文字を含む名前; print(name.strip(".csv")文字集合で両端を削る, name.removesuffix(".csv")指定した接尾辞を除く)stripは.・c・s・vという文字の集合を両端から取り除くため、iviまで削ります。removesuffixは末尾の.csv一つだけを取り除き、civicを残します。
7数値へ変換して表示を整える
個数はint、単価はfloatへ変換し、桁幅と小数点以下二桁を指定します。
quantity = int(quantity_text); price = float(price_text)計算用の数値へ変換; line = f"{item:<8} qty={quantity:03d} price={price:07.2f} total={quantity * price:.2f}"左寄せ・ゼロ埋め・小数桁; print(line)整形した行; print(quantity, price, quantity_text, price_text)計算値と元の文字列表示は個数003、単価0120.50、合計361.50です。元の整数は3、floatは120.5のままで、表示書式によって数量が変わるわけではありません。丸めた表示が後の計算へ必要なら、表示と計算値の扱いを別に決めます。
まとめ
区切り、空項目、空白、接尾辞の意味を保って加工します。
検索結果や表示の文字列を、元の値や数値そのものと混同しません。
操作履歴と解説を振り返れます。
Python 3
raw = " pen , 03 , 120.5 "; parts = raw.split(","); print(repr(raw), parts)' pen , 03 , 120.5 ' [' pen ', ' 03 ', ' 120.5 ']
item, quantity_text, price_text = [part.strip() for part in parts]; print(item, quantity_text, price_text); print(repr(raw))pen 03 120.5 ' pen , 03 , 120.5 '
print("a b".split(), "a b".split(" ")); print("pen,,120.5".split(",")); print("note=blue=pen".split("=", 1))['a', 'b'] ['a', '', 'b'] ['pen', '', '120.5'] ['note', 'blue=pen']
print(item.find("pen"), item.find("missing")); print("pen" in item, "missing" in item)0 -1 True False
renamed = item.replace("pen", "marker"); print(item, renamed, "pencil".replace("pen", "marker")); print(",".join([renamed, quantity_text, price_text]))pen marker markercil marker,03,120.5
name = "civic.csv"; print(name.strip(".csv"), name.removesuffix(".csv"))ivi civic
quantity = int(quantity_text); price = float(price_text); line = f"{item:<8} qty={quantity:03d} price={price:07.2f} total={quantity * price:.2f}"; print(line); print(quantity, price, quantity_text, price_text)pen qty=003 price=0120.50 total=361.50 3 120.5 03 120.5
演習完了