簡體   English   中英

如何按值 Python 對 JSON 文件進行排序

[英]How to sort JSON file by value Python

我有一個大的 JSON 文件,其中包含如下時區:

{
   "timezones":[
      {
         "id":1,
         "name":"(UTC) Coordinated Universal Time",
         "utc_offset":"+0"
      },
      {
         "id":2,
         "name":"(UTC+8:45) Australian Central Standard Time",
         "utc_offset":"+8:45"
      },
      {
         "id":3,
         "name":"(UTC-5) Acre Time",
         "utc_offset":"-5"
      },
      {
         "id":4,
         "name":"(UTC+8:45) Australian Central Western Standard Time",
         "utc_offset":"+8:45"
      }
   ]
}

我正在嘗試根據from - to +utc_offset值對其進行排序,如果utc_offset相同,則按字母順序按name排序。 所以想要的結果應該是這樣的:

{
   "timezones":[
      {
         "id":3,
         "name":"(UTC-5) Acre Time",
         "utc_offset":"-5"
      },
      {
         "id":1,
         "name":"(UTC) Coordinated Universal Time",
         "utc_offset":"+0"
      },
      {
         "id":2,
         "name":"(UTC+8:45) Australian Central Standard Time",
         "utc_offset":"+8:45"
      },
      {
         "id":4,
         "name":"(UTC+8:45) Australian Central Western Standard Time",
         "utc_offset":"+8:45"
      }
   ]
}

我嘗試使用以下代碼:

lines = lines.sort(int(json['timezones']['utc_offset']), reverse=True)

print(lines)

但它顯示錯誤AttributeError: 'dict' object has no attribute 'sort'

我該怎么做?

也許像這樣使用正則表達式來解析utc_offset

adict = {
    "timezones": [
        {
            "id": 1,
            "name": "(UTC) Coordinated Universal Time",
            "utc_offset": "+0"
        },
        {
            "id": 2,
            "name": "(UTC+8:45) Australian Central Standard Time",
            "utc_offset": "+8:45"
        },
        {
            "id": 3,
            "name": "(UTC-5) Acre Time",
            "utc_offset": "-5"
        },
        {
            "id": 4,
            "name": "(UTC+8:45) Australian Central Western Standard Time",
            "utc_offset": "+8:45"
        }
    ]
}

timezones = adict['timezones']

pattern = re.compile(r'^(?P<sign>[+-])(?P<hour>\d+):?(?P<minutes>\d+)?')


def get_time(string):
    m = pattern.match(string)
    if not m:
        return False
    sign, hour, minutes = m.groupdict().values()
    result = int(hour) * 60 + (int(minutes) if minutes else 0)
    result = -result if sign == '-' else result
    return result


print(sorted(timezones, key=lambda x: (get_time(x['utc_offset']), x['name'])))

Output:

[
    {'id': 3, 'name': '(UTC-5) Acre Time', 'utc_offset': '-5'},
    {'id': 1, 'name': '(UTC) Coordinated Universal Time', 'utc_offset': '+0'},
    {'id': 2, 'name': '(UTC+8:45) Australian Central Standard Time', 'utc_offset': '+8:45'},
    {'id': 4, 'name': '(UTC+8:45) Australian Central Western Standard Time', 'utc_offset': '+8:45'}
]
json = {
   "timezones":[
      {
         "id":1,
         "name":"(UTC) Coordinated Universal Time",
         "utc_offset":"+0"
      },
      {
         "id":2,
         "name":"(UTC+8:45) Australian Central Standard Time",
         "utc_offset":"+8:45"
      },
      {
         "id":3,
         "name":"(UTC-5) Acre Time",
         "utc_offset":"-5"
      },
      {
         "id":4,
         "name":"(UTC+8:45) Australian Central Western Standard Time",
         "utc_offset":"+8:45"
      }
   ]
}

def to_mins(e):
    offset = e['utc_offset']
    sign = 1 if offset[0] == '+' else -1
    hm = offset[1:].split(':')
    h, m = (hm[0], 0) if len(hm) == 1 else hm
    return sign * (60 * int(h) + int(m))



print(sorted(json['timezones'], key=to_mins))

印刷

[{'id': 3, 'name': '(UTC-5) Acre Time', 'utc_offset': '-5'},
 {'id': 1, 'name': '(UTC) Coordinated Universal Time', 'utc_offset': '+0'},
 {'id': 2,
  'name': '(UTC+8:45) Australian Central Standard Time',
  'utc_offset': '+8:45'},
 {'id': 4,
  'name': '(UTC+8:45) Australian Central Western Standard Time',
  'utc_offset': '+8:45'}]

所以首先我們將時區字符串轉換為數值,然后使用排序后的 function 進行排序。 如果要按降序獲得結果,可以將 boolean 參數的值反向更改。

def get_minutes_tz(str_tz):
    min_tz = None
    # add more checks on the format of the timezone string (you can also use regexes)
    if len(str_tz)>0 and isinstance(str_tz, str) and (str_tz.startswith('+')  or str_tz.startswith('-')):
        splits = str_tz[1:].split(':')
        min_tz = int(str_tz[0] + str(int(splits[0])*60 if len(splits)>0 else 0 + int(splits[1] if len(splits)>1 else 0)))
    return min_tz

sorted(d['timezones'], key=lambda k: get_minutes_tz(k['utc_offset']), 
       reverse=False)

結果:

[{'id': 3, 'name': '(UTC-5) Acre Time', 'utc_offset': '-5'},
 {'id': 1, 'name': '(UTC) Coordinated Universal Time', 'utc_offset': '+0'},
 {'id': 2,
  'name': '(UTC+8:45) Australian Central Standard Time',
  'utc_offset': '+8:45'},
 {'id': 4,
  'name': '(UTC+8:45) Australian Central Western Standard Time',
  'utc_offset': '+8:45'}]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM