【问题标题】:python sort list of json by valuepython按值排序json列表
【发布时间】:2015-01-11 12:55:49
【问题描述】:

我有一个由 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 异常。有没有例外的方法来做到这一点?

【问题讨论】:

    标签: python json lambda sorted


    【解决方案1】:

    编写一个使用try...except 处理KeyError 的函数,然后将其用作key 参数而不是您的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)
    

    【讨论】:

      【解决方案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'}}
      

      尽管如此,我仍然会遵循 Ferdinand 建议的 EAFP principle - 这样您还可以处理 page 密钥也丢失的情况。让它失败并处理它比检查各种极端情况要容易得多。

      【讨论】:

      • 如何将 json 文件分配给行,这样如果我有 100 万行,它必须动态地加载,那么它就不会正确加载,这就是原因
      【解决方案3】:
      # sort json
      lines = sorted(lines, key=lambda k: k['page'].get('update_time', 0), reverse=True)
      

      【讨论】:

        【解决方案4】:
        def get_sortest_key(a: dict, o: dict):
            v = None
            k = None
            for key, value in a.items():
                if v is None:
                    v = value
                    k = key
                    continue
                if v > value:
                    v = value
                    k = key
            o.update({k: v})
            a.pop(k)
            if a:
                get_sortest_key(a, o)
            else:
                return
        
        
        def call(o):
            a = {'a': 9, 'b': 1, 'c': 3, 'k': 3, 'l': -1, 's': 100}
            z = get_sortest_key(a, o)
            print(o)
        
        
        o={}    
        call(o)
        

        【讨论】:

        • 添加一些关于您的代码如何解决原始问题的解释会很有用。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-14
        • 1970-01-01
        • 2018-08-11
        • 1970-01-01
        • 2021-06-18
        • 2019-06-09
        相关资源
        最近更新 更多