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

Time:12-15

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.

CodePudding user response:

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

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

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 (a.k.a. 6AM - 5AM) by 6 hours (i.e. 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

CodePudding user response:

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"])),
)

  • Related