python - tutorial - todo sobre elasticsearch
Python ordena la lista de json por valor (3)
Tengo un archivo compuesto por JSON, cada una línea, y quiero ordenar el archivo por update_time revertido.
archivo JSON de muestra:
{ "page": { "url": "url1", "update_time": "1415387875"}, "other_key": {} }
{ "page": { "url": "url2", "update_time": "1415381963"}, "other_key": {} }
{ "page": { "url": "url3", "update_time": "1415384938"}, "other_key": {} }
quiere salida:
{ "page": { "url": "url1", "update_time": "1415387875"}, "other_key": {} }
{ "page": { "url": "url3", "update_time": "1415384938"}, "other_key": {} }
{ "page": { "url": "url2", "update_time": "1415381963"}, "other_key": {} }
mi código:
#!/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
El código funciona bien con el archivo JSON de muestra, pero si un JSON no tiene ''update_time'', generará la excepción KeyError. ¿Hay formas no excepcionales de hacer esto?
Escriba una función que use try...except
para manejar KeyError
, luego use esto como el argumento key
en lugar de su lambda.
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)
Puedes usar dict.get()
con un valor predeterminado:
lines = sorted(lines, key=lambda k: k[''page''].get(''update_time'', 0), reverse=True)
Ejemplo:
>>> 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''}}
Sin embargo, aún seguiría el principio de EAFP
que Ferdinand sugirió, de esta manera usted también manejaría casos en los que también falta la clave de la page
. Mucho más fácil dejarlo fallar y manejarlo que revisar todo tipo de casos de esquina.
#sort json
lines = sorted(lines, key=lambda k: k[''page''].get(''update_time'', 0), reverse=True)