コンピューターサイエンス入門:理論編
重複データを 1NF に変換 (フラットなリスト化)
この回でやること
タグを1行1値に整える考え方を読み解き、空白・空文字・重複の扱いを確かめます。
- 読む 約 7 分
- 最後にクイズ 1 問
1つのセルに詰めると、あとで数えられない
蔵書の一覧を表計算ソフトで作ると、タグの欄はたいていこうなります。
| 書名 | タグ |
|---|---|
| 深夜特急 | 旅行, エッセイ |
| 銀河鉄道の夜 | 童話 |
| 地球の歩き方 | 旅行 |
眺めるぶんには困りません。困るのは「旅行タグの本は何冊あるか」を数えるときです。欄をそのまま辞書のキーにすると、「旅行, エッセイ」と「旅行」は別の値です。旅行の本は2冊あるのに、「旅行」と完全に一致する行は1行しかありません。部分一致で探すと「旅行記」のような別のタグまで拾うおそれがあります。
1つの欄には1つの値を置く
タグを1つずつに分け、書名とタグの組を1行にします。深夜特急は「旅行」と「エッセイ」の2行になります。第一正規形(1NF)では、各欄にその用途でひとまとまりとして扱える値を置きます。この例ではタグを個別に検索・集計するので、タグのリストを1つの欄に詰めません。
行を増やしても、本が増えたわけではありません。本とタグの対応が増えただけです。同名の本を区別するなら、書名だけでなく本の番号も残します。表を分ける場合も、その番号で元の本と結び付けられます。
分ける道具は split、そのあと strip
カンマで区切る split と、前後の空白を落とす strip の結果を読みます。JavaScriptでは空白を落とす操作を trim と呼びます。
Python
print("旅行, エッセイ".split(","))
# ['旅行', ' エッセイ']
print(" エッセイ".strip())
# 'エッセイ'分けただけでは2つ目の先頭に空白が残ります。そのまま比較すると「エッセイ」と「 エッセイ」は別物です。カンマと空白をまとめて区切りにすると、空白のない「旅行,エッセイ」を分けられません。カンマで分けてから、各値の空白を落とす順にします。
消し忘れのカンマがある「旅行, , エッセイ」は、空白を落とすと「旅行」「空文字」「エッセイ」になります。空文字を残すと、タグ名のない行まで1件に数えてしまいます。この読み方では空文字を除きます。同じタグが繰り返されていても、分割と空白除去だけでは重複は消えません。
例題で確かめる
蔵書に「旅の記録」のタグ「旅行, , 文化」と、「台所の本」のタグ「料理」があります。カンマで分け、前後の空白を落とし、空文字を除いた表を読みます。
| 書名 | タグ |
|---|---|
| 旅の記録 | 旅行 |
| 旅の記録 | 文化 |
| 台所の本 | 料理 |
最初の本から2行、次の本から1行で、結果は2 + 1 = 3行です。「旅行」と完全に一致する行は1行です。空のタグは数えず、書名とタグの対応は保っています。