次のような、年が変わった時だけ年数が入っている日付のデータを datetime でフォーマットしたかった。
data = [ "2012年10月8日", "10月15日", # … "12月24日", "2013年1月7日", "1月14日", # … "12月26日", "2014年1月9日", "1月16日", # … ]
年数を global 変数に置いておいて \d+年
が出現する度に変数を更新して使えば済むのだけど、global の変数を更新していくのはイケてない感があります。年数内部で保持できるクロージャにできるとスッキリしそうです。
クロージャーを使ってフォーマットする
from re import search def froamt(_year): year = _year def _format(date): nonlocal year match = search(r'\d+年', date) if match: year = match.group() ymd = date else: ymd = f'{year}{date}' return ymd return _format START_YEAR = '2012年' f = froamt(START_YEAR) format_data = [f(v) for v in data]
これで全て YYYY年M月D日
という形式に変換することができました。
Python のスコープはまだよく解ってないのですが、クロージャーの内側の関数の中で外の関数で定義された変数を更新するには nonlocal
キーワードでアクセスできるように宣言してあげる必要がありました。
datetime で変換する
データが全て YYYY年M月D日
と言う形にできたので、これを datetime.date
でオブジェクトにして strftime
でフォーマットしてあげれば良さそうです。
フォーマットする関数を追加します。
from re import search, split from datetime import date as dt def format_date(date_str): date = dt(*[int(n) for n in split('[年月日]', date_str) if n]) return date.strftime('%Y-%m-%d (%a)') def froamt(_year): year = _year def _format(date): nonlocal year match = search(r'\d+年', date) if match: year = match.group() ymd = date else: ymd = f'{year}{date}' # datetime でフォーマットしたものを返す return format_date(ymd) return _format START_YEAR = '2012年' f = froamt(START_YEAR) format_data = [f(v) for v in data]
フォーマット関数内のフォーマット方法を変えれば好きな形にフォーマットできます。
これで YYYY-MM-DD (What day of the week)
の形のデータに整形することができました!
date オブジェクト化するのにYYYY年M月D日
な文字列を配列にして datetime.date(year, month, date)
でオブジェクト化しているのですが、もっとスマートな変換方法がありそうな気がしています。
所感
Python でも 関数を返す関数を作成できることが判ったので良かったです。(個人的に Python と JavaScript 似てるな〜って感じてます。)
クロージャーの内部の関数から外部の変数にアクセスするのに nonlocal
宣言が必要で、このあたりのスコープまわりは理解が足りてないので引き続き調べて理解しておきたいです。
[参考]
- クロージャ - JavaScript | MDN
- 関数がネストされたPythonコードで関数の内側で変更した変数を関数の外側から参照する方法を調べてみた | Developers.IO
- Python のクロージャと nonlocal ってなに? | 民主主義に乾杯
- Pythonのクロージャ、nonlocalの使い方 Koa
- Python - 日付フォーマットを設定する | murashun.jp

ゼロから作るDeep Learning ❷ ―自然言語処理編
- 作者:斎藤 康毅
- 発売日: 2018/07/21
- メディア: 単行本(ソフトカバー)

- 発売日: 2014/11/05
- メディア: Blu-ray
日付でお察しの方が居るかもですがアイカツ! 放送日のリストでした