私はJSONで構成されたファイルを持っていますが、それぞれが行であり、update_timeを逆にしてファイルをソートしたいです。
サンプルJSONファイル:
{ "page": { "url": "url1", "update_time": "1415387875"}, "other_key": {} }
{ "page": { "url": "url2", "update_time": "1415381963"}, "other_key": {} }
{ "page": { "url": "url3", "update_time": "1415384938"}, "other_key": {} }
出力したい:
{ "page": { "url": "url1", "update_time": "1415387875"}, "other_key": {} }
{ "page": { "url": "url3", "update_time": "1415384938"}, "other_key": {} }
{ "page": { "url": "url2", "update_time": "1415381963"}, "other_key": {} }
私のコード:
#!/bin/env python
#coding: utf8
import sys
import os
import json
import operator
#load json from file
lines = []
while True:
line = sys.stdin.readline()
if not line: break
line = line.strip()
json_obj = json.loads(line)
lines.append(json_obj)
#sort json
lines = sorted(lines, key=lambda k: k['page']['update_time'], reverse=True)
#output result
for line in lines:
print line
コードはサンプルJSONファイルで正常に機能しますが、JSONに「update_time」がない場合、KeyError例外が発生します。これを行う非例外的な方法はありますか?
try...except
を使用してKeyError
を処理する関数を作成し、これをラムダの代わりにkey
引数として使用します。
def extract_time(json):
try:
# Also convert to int since update_time will be string. When comparing
# strings, "10" is smaller than "2".
return int(json['page']['update_time'])
except KeyError:
return 0
# lines.sort() is more efficient than lines = lines.sorted()
lines.sort(key=extract_time, reverse=True)
dict.get()
をデフォルト値で使用できます:
lines = sorted(lines, key=lambda k: k['page'].get('update_time', 0), reverse=True)
例:
>>> lines = [
... {"page": {"url": "url1", "update_time": "1415387875"}, "other_key": {}},
... {"page": {"url": "url2", "update_time": "1415381963"}, "other_key": {}},
... {"page": {"url": "url3", "update_time": "1415384938"}, "other_key": {}},
... {"page": {"url": "url4"}, "other_key": {}},
... {"page": {"url": "url5"}, "other_key": {}}
... ]
>>> lines = sorted(lines, key=lambda k: k['page'].get('update_time', 0), reverse=True)
>>> for line in lines:
... print line
...
{'other_key': {}, 'page': {'url': 'url1', 'update_time': '1415387875'}}
{'other_key': {}, 'page': {'url': 'url3', 'update_time': '1415384938'}}
{'other_key': {}, 'page': {'url': 'url2', 'update_time': '1415381963'}}
{'other_key': {}, 'page': {'url': 'url4'}}
{'other_key': {}, 'page': {'url': 'url5'}}
ただし、フェルディナンドが示唆した EAFP
原則 に従います。この方法では、page
キーも欠落している場合も処理できます。あらゆる種類のコーナーケースをチェックするよりも、失敗させて処理する方がはるかに簡単です。
# sort json
lines = sorted(lines, key=lambda k: k['page'].get('update_time', 0), reverse=True)