Подтвердить что ты не робот

Список сортировки json по значению python

У меня есть файл, состоящий из 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. Существуют ли исключения для этого?

4b9b3361

Ответ 1

Напишите функцию, которая использует try...except обработки KeyError, а затем используйте ее в качестве аргумента key вместо лямбда- KeyError.

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)

Ответ 2

Вы можете использовать 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. Гораздо проще дать ему сбой и обработать его, чем проверять всевозможные угловые случаи.

Ответ 3

# sort json
lines = sorted(lines, key=lambda k: k['page'].get('update_time', 0), reverse=True)