简体   繁体   中英

How to sort a list of dictionary with recurring specific order in python?

My list:

old_list = [
    {'date': '2021-11-12', 'hour': '1.0'}, 
    {'date': '2021-11-12', 'hour': '3.0'}, 
    {'date': '2021-11-12', 'hour': '12.0'}, 
    {'date': '2021-11-12', 'hour': '10.0'},
    {'date': '2021-11-12', 'hour': '11.0'},
    {'date': '2021-11-12', 'hour': '2.0'},
    {'date': '2021-11-13', 'hour': '3.0'},
    {'date': '2021-11-13', 'hour': '10.0'},
    {'date': '2021-11-13', 'hour': '1.0'},
    {'date': '2021-11-13', 'hour': '2.0'},
    {'date': '2021-11-13', 'hour': '11.0'},
    {'date': '2021-11-13', 'hour': '12.0'},
]

I want to sort them by the date and then the hour in such order (10PM - 3AM of the same day):
Note: It needs to be in that exact order as the example below

old_list = [
    {'date': '2021-11-12', 'hour': '10.0'}, 
    {'date': '2021-11-12', 'hour': '11.0'}, 
    {'date': '2021-11-12', 'hour': '12.0'}, 
    {'date': '2021-11-12', 'hour': '1.0'},
    {'date': '2021-11-12', 'hour': '2.0'},
    {'date': '2021-11-12', 'hour': '3.0'},
    {'date': '2021-11-13', 'hour': '10.0'},
    {'date': '2021-11-13', 'hour': '11.0'},
    {'date': '2021-11-13', 'hour': '12.0'},
    {'date': '2021-11-13', 'hour': '1.0'},
    {'date': '2021-11-13', 'hour': '2.0'},
    {'date': '2021-11-13', 'hour': '3.0'},
]

How is this possible?

Additional Information
Use case of this is that I have a 24-hour range data of a few dates. I want to sort them by date and sort them from 6AM - 5AM manner.

IIUC, one way using modulo to reflect the shifted timeline:

sorted(old_list, key=lambda x: (x["date"], (float(x["hour"]) - 6)%24))

Output:

[{'date': '2021-11-12', 'hour': '10.0'},
 {'date': '2021-11-12', 'hour': '11.0'},
 {'date': '2021-11-12', 'hour': '12.0'},
 {'date': '2021-11-12', 'hour': '1.0'},
 {'date': '2021-11-12', 'hour': '2.0'},
 {'date': '2021-11-12', 'hour': '3.0'},
 {'date': '2021-11-13', 'hour': '10.0'},
 {'date': '2021-11-13', 'hour': '11.0'},
 {'date': '2021-11-13', 'hour': '12.0'},
 {'date': '2021-11-13', 'hour': '1.0'},
 {'date': '2021-11-13', 'hour': '2.0'},
 {'date': '2021-11-13', 'hour': '3.0'}]

Insight:

  • (float(x["hour"]) - 6) % 24 : Shifts your distribution of time (aka 6AM - 5AM) by 6 hours (ie usual 24 hour). Then the shifted hours are rebounded into 24 hour boundary.

Thus the hours in the original data are transformed into:

1.0 --> 19
3.0 --> 21
12.0 --> 6
10.0 --> 4
11.0 --> 5
2.0 --> 20
3.0 --> 21
10.0 --> 4
1.0 --> 19
2.0 --> 20
11.0 --> 5
12.0 --> 6

If time complexity doesn't matter (unless hour_order has only few elements everything will be fine), here it is:

from datetime import datetime

hour_order = ["10.0", "11.0", "12.0", ...]
sorted(
    old_list,
    key=lambda d: (datetime.strptime(d["date"], "%Y-%m-%d").date(), hour_order.index(d["hour"])),
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM