I have a couple comments on this one:
"Best" is ambiguous. It could mean minimized algorithmic complexity, minimized runtime, minimized memory usage, simplest to implement or read, least amount of code, etc.
Unless you have thousands of entries, it might not be worth optimizing your data structure or algorithm. The community's accepted best practice is to profile and optimize what's slow about your entire program.
A simple implementation could be nothing more than joining the lists and sorting them with the sorted
built-in. For example, here are a few options you might consider for sorting:
import datetime
a = ['7-1-1987', '1-1-1990']
b = ['7-2-1987', '1-5-1990']
c = ['7-1-1987', '1-3-1990']
d = ['1-10-1985', '7-10-1986']
# hold on to list name
a = [(i, 'a') for i in a] # [(date, list_name), ...]
b = [(i, 'b') for i in b]
c = [(i, 'c') for i in c]
d = [(i, 'd') for i in d]
dates = a + b + c + d # combine into one flat list
for i in dates: print(i)
Output
('7-1-1987', 'a')
('1-1-1990', 'a')
('7-2-1987', 'b')
('1-5-1990', 'b')
('7-1-1987', 'c')
('1-3-1990', 'c')
('1-10-1985', 'd')
('7-10-1986', 'd')
Approach 1 - Parse each date string to a datetime object, sort them in place, and output a list of datetime objects.
dates_1 = [(datetime.datetime.strptime(d, '%m-%d-%Y').date(), l) for d, l in dates]
dates_1.sort()
for i in dates_1: print(i)
Output
(datetime.date(1985, 1, 10), 'd')
(datetime.date(1986, 7, 10), 'd')
(datetime.date(1987, 7, 1), 'a')
(datetime.date(1987, 7, 1), 'c')
(datetime.date(1987, 7, 2), 'b')
(datetime.date(1990, 1, 1), 'a')
(datetime.date(1990, 1, 3), 'c')
(datetime.date(1990, 1, 5), 'b')
Approach 2 - Sort the dates using a lambda function that parses them on the fly, and output a (new) list of strings.
dates_2 = sorted(dates, key=lambda d: (datetime.datetime.strptime(d[0], '%m-%d-%Y').date(), d[1]))
for i in dates_2: print(i)
Output
('1-10-1985', 'd')
('7-10-1986', 'd')
('7-1-1987', 'a')
('7-1-1987', 'c')
('7-2-1987', 'b')
('1-1-1990', 'a')
('1-3-1990', 'c')
('1-5-1990', 'b')
Approach 3 - Use heapq.merge to sort more efficiently. Credit to @friendlydog for the suggestion.
import datetime
import heapq
a = ['7-1-1987', '1-1-1990']
b = ['7-2-1987', '1-5-1990']
c = ['7-1-1987', '1-3-1990']
d = ['1-10-1985', '7-10-1986']
def strs_to_dates(date_strs, list_name):
"""
Convert a list of date strings to a generator of (date, str) tuples.
"""
return ((datetime.datetime.strptime(date, '%m-%d-%Y').date(), list_name) for date in date_strs)
a = strs_to_dates(a, 'a')
b = strs_to_dates(b, 'b')
c = strs_to_dates(c, 'c')
d = strs_to_dates(d, 'd')
dates_3 = heapq.merge(a, b, c, d)
for i in dates_3: print(i)
Output
(datetime.date(1985, 1, 10), 'd')
(datetime.date(1986, 7, 10), 'd')
(datetime.date(1987, 7, 1), 'a')
(datetime.date(1987, 7, 1), 'c')
(datetime.date(1987, 7, 2), 'b')
(datetime.date(1990, 1, 1), 'a')
(datetime.date(1990, 1, 3), 'c')
(datetime.date(1990, 1, 5), 'b')
Notes:
- I assumed the format of your input strings is 'day-month-year'.
- I assumed when the same date is in multiple lists, that you'd want to secondarily sort alphanumerically by list name.
- I left formatting the output list as an exercise for the reader.
- Both examples working under Python 2 / 3.
In this example, the key
argument is a lambda. Without that it would sort the strings alphabetically. This lets us override that and sort by year > month > day.
A more elaborate implementation could take advantage of the guarantee that the lists are pre-sorted. Wikipedia has a list of merge algorithms to consider.