I have a big JSON file that contains timezones like the following:
{
"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"
}
]
}
I'm trying to sort it according to the utc_offset
values from - to
, if the utc_offset
are identical, then by name
alphabetically. So The wanted result should be like this:
{
"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"
}
]
}
Using the following code I tried:
lines = lines.sort(int(json['timezones']['utc_offset']), reverse=True)
print(lines)
But it's showing an error AttributeError: 'dict' object has no attribute 'sort'
How I may do this?
CodePudding user response:
Maybe something like this using regexps for parsing 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'}
]
CodePudding user response:
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))
prints
[{'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'}]
CodePudding user response:
So first we transform the timezone strings into numeric values, then sort using the sorted function. If you want to get the results in descending order, you can change the value of the boolean parameter reverse.
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)
result:
[{'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'}]