はじめに
Pythonを勉強するため、東京工業大学の岡崎教授が出題されている言語処理100本ノック 2015を解いていきます。
より深く理解するため、別解や利用したライブラリの解説もまとめていきます。
環境
Python3.6
OS : mac
問題
第3章: 正規表現
Wikipediaの記事を以下のフォーマットで書き出したファイルjawiki-country.json.gzがある.
- 1行に1記事の情報がJSON形式で格納される
- 各行には記事名が"title"キーに,記事本文が"text"キーの辞書オブジェクトに格納され,そのオブジェクトがJSON形式で書き出される
- ファイル全体はgzipで圧縮される
以下の処理を行うプログラムを作成せよ.
20. JSONデータの読み込み
Wikipedia記事のJSONファイルを読み込み,「イギリス」に関する記事本文を表示せよ.問題21-29では,ここで抽出した記事本文に対して実行せよ.
解答
import gzip
import json
def read_wiki(fname, title):
"""指定のタイトルの記事本文を表示する。
"""
# ファイルを解凍して読み込む
with gzip.open(fname, 'rt') as data_file:
for line in data_file:
# json to dict
data_json = json.loads(line)
# 指定のタイトルの本文を返す
if data_json['title'] == title:
return data_json['text']
def main():
fname = 'jawiki-country.json.gz'
print(read_wiki(fname, 'イギリス'))
if __name__ == '__main__':
main()
出力
{{基礎情報 国
|略名 = イギリス
|日本語国名 = グレートブリテン及び北アイルランド連合王国
|公式国名 = {{lang|en|United Kingdom of Great Britain and Northern Ireland}}<ref>英語以外での正式国名:<br/>
*{{lang|gd|An Rìoghachd Aonaichte na Breatainn Mhòr agus Eirinn mu Thuath}}([[スコットランド・ゲール語]])<br/>
*{{lang|cy|Teyrnas Gyfunol Prydain Fawr a Gogledd Iwerddon}}([[ウェールズ語]])<br/>
*{{lang|ga|Ríocht Aontaithe na Breataine Móire agus Tuaisceart na hÉireann}}([[アイルランド語]])<br/>
(中略)
{{OECD}}
{{イギリス連邦}}
{{デフォルトソート:いきりす}}
[[Category:イギリス|*]]
[[Category:英連邦王国|*]]
[[Category:G8加盟国]]
[[Category:欧州連合加盟国]]
[[Category:海洋国家]]
[[Category:君主国]]
[[Category:島国|くれいとふりてん]]
[[Category:1801年に設立された州・地域]]
解説
3章からWikipediaの記事から問題が出るようになった。
お世話になるイギリスのページはこちら。
まずは、jawiki-country.json.gz
を確認してみます。
ダウンロードしてツールを使って解凍しました。
中身は1行ごとに国の情報がJSON形式でまとまっています。
{"title":"国名1", "text":"記事本文"}
{"title":"国名2", "text":"記事本文"}
構成がわかったので、Wikipedia記事を読み込み記事を検索する関数read_wiki(fname, title)
を作成します。
拡張子.gz
はgzipの圧縮ファイルです。pythonの標準モジュールgzipを使って解凍しました。
# ファイルを解凍して読み込む
with gzip.open(fname, 'rt') as data_file:
for line in data_file:
これで1行ずつ文字列を読み込みます。
fname
はファイルのパスです。コードとファイルを同じフォルダに置いたので、fname = 'jawiki-country.json.gz'
とします。
続いて、1行がJSON形式になっているところを、扱いやすいdictにデコードします。 こちらも、pythonの標準モジュールjsonを使います。
# json to dict
data_json = json.loads(line)
dictへのデコードはjson.load()
を利用しました。
>> import >> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') ['foo', {'bar': ['baz', None, 1.0, 2]}]
引用:json
jsonのnullは、Noneに変換してくれるみたいです。
# 指定のタイトルの本文を返す
if data_json['title'] == title:
return data_json['text']
最後に、指定のtitleの記事の本文(text)を返します。
参考
続いての記事
前の問題:19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる
次の問題:21. カテゴリ名を含む行を抽出