Home > Blockchain >  Python: sort a list of dictionary using mutliple keys
Python: sort a list of dictionary using mutliple keys

Time:08-25

I have a list of dictionary of the previous 12 months values. I would like to sort it based on year and then month, without importing any extra libraries.

Current Input

[{'key': '2021 Mar', 'value': '101.239'}, {'key': '2021 May', 'value': '101.883'}, {'key': '2021 Sep', 'value': '102.657'}, {'key': '2021 Oct', 'value': '102.95'}, {'key': '2021 Nov', 'value': '103.959'}, {'key': '2022 Feb', 'value': '105.379'}, {'key': '2022 Apr', 'value': '106.547'}, {'key': '2022 Jan', 'value': '104.472'}, {'key': '2022 Jul', 'value': '108.836'}{'key': '2022 Mar', 'value': '106.691'}, {'key': '2022 May', 'value': '107.598'}, {'key': '2022 Jun', 'value': '108.671'},  ]

Desired Output: In ascending order by Year and then Month

[{'key': '2021 Mar', 'value': 101.239}, ......, {'key': '2022 Jul', 'value': '108.836'}]

I tried to re-create a new list-dictionary with Year and Month keys. From there, how do I proceed?

data_12= [{'key': '2021 Mar', 'value': '101.239'}, {'key': '2021 May', 'value': '101.883'}, {'key': '2021 Sep', 'value': '102.657'}, {'key': '2021 Oct', 'value': '102.95'}, {'key': '2021 Nov', 'value': '103.959'}, {'key': '2022 Feb', 'value': '105.379'}, {'key': '2022 Apr', 'value': '106.547'}, {'key': '2022 Jan', 'value': '104.472'}, {'key': '2022 Jul', 'value': '108.836'}{'key': '2022 Mar', 'value': '106.691'}, {'key': '2022 May', 'value': '107.598'}, {'key': '2022 Jun', 'value': '108.671'},  ]

data_12_new=[]
data_12_dic={}  

for i in data_12:
    data_12_dic['key']=i['key']
    data_12_dic['value']=i['value']
    data_12_dic['yr']= i['key'][0:4]
    data_12_dic['mth']= i['key'][5:8]
    
    data_12_new.append(data_12_dic)

#sort based on 1 key
newlist = sorted(data_12, key=lambda d: d['mth']) 

# How to sort based on "yr" and "mth"?

CodePudding user response:

You can sort the list based on datetime objects using datetime.datetime.strptime:

from datetime import datetime

lst = [{'key': '2021 Mar', 'value': '101.239'}, {'key': '2021 May', 'value': '101.883'}, {'key': '2021 Sep', 'value': '102.657'}, {'key': '2021 Oct', 'value': '102.95'}, {'key': '2021 Nov', 'value': '103.959'}, {'key': '2022 Feb', 'value': '105.379'}, {'key': '2022 Apr', 'value': '106.547'}, {'key': '2022 Jan', 'value': '104.472'}, {'key': '2022 Jul', 'value': '108.836'}, {'key': '2022 Mar', 'value': '106.691'}, {'key': '2022 May', 'value': '107.598'}, {'key': '2022 Jun', 'value': '108.671'}]

output = sorted(lst, key=lambda d: datetime.strptime(d['key'], '%Y %b'))

print(output)
# [{'key': '2021 Mar', 'value': '101.239'},
#  {'key': '2021 May', 'value': '101.883'},
#  {'key': '2021 Sep', 'value': '102.657'},
#  {'key': '2021 Oct', 'value': '102.95'},
#  {'key': '2021 Nov', 'value': '103.959'},
#  {'key': '2022 Jan', 'value': '104.472'},
#  {'key': '2022 Feb', 'value': '105.379'},
#  {'key': '2022 Mar', 'value': '106.691'},
#  {'key': '2022 Apr', 'value': '106.547'},
#  {'key': '2022 May', 'value': '107.598'},
#  {'key': '2022 Jun', 'value': '108.671'},
#  {'key': '2022 Jul', 'value': '108.836'}]

If (for whatever reason) you don't want to use the module, you need to manually let the python know the ordering among the months:

months = {m: i for i, m in enumerate(['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'])}

lst = [{'key': '2021 Mar', 'value': '101.239'}, {'key': '2021 May', 'value': '101.883'}, {'key': '2021 Sep', 'value': '102.657'}, {'key': '2021 Oct', 'value': '102.95'}, {'key': '2021 Nov', 'value': '103.959'}, {'key': '2022 Feb', 'value': '105.379'}, {'key': '2022 Apr', 'value': '106.547'}, {'key': '2022 Jan', 'value': '104.472'}, {'key': '2022 Jul', 'value': '108.836'}, {'key': '2022 Mar', 'value': '106.691'}, {'key': '2022 May', 'value': '107.598'}, {'key': '2022 Jun', 'value': '108.671'}]

def key_fun(dct):
    year, month = dct['key'].split()
    return int(year), months[month]

output = sorted(lst, key=key_fun)

CodePudding user response:

You can sort them easily once you parse the year/date string into a datetime object using datetime.strptime().

%Y is the year, and %b is the month’s abbreviated name (which can be different depending on locale). See strftime() and strptime() Format Codes.

from datetime import datetime

dicts = [{'key': '2021 Mar', 'value': '101.239'}, 
              {'key': '2021 May', 'value': '101.883'}, 
              {'key': '2021 Sep', 'value': '102.657'}, 
              {'key': '2021 Oct', 'value': '102.95'}, 
              {'key': '2021 Nov', 'value': '103.959'}, 
              {'key': '2022 Feb', 'value': '105.379'}, 
              {'key': '2022 Apr', 'value': '106.547'}, 
              {'key': '2022 Jan', 'value': '104.472'}, 
              {'key': '2022 Jul', 'value': '108.836'}, 
              {'key': '2022 Mar', 'value': '106.691'}, 
              {'key': '2022 May', 'value': '107.598'}, 
              {'key': '2022 Jun', 'value': '108.671'},
              ]

sorted_dicts = sorted(dicts, key=lambda x: datetime.strptime(x["key"], "%Y %b"))

for d in sorted_dicts:
    print(d)
  • Related