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