我有几个关于这个的:
“最佳”不明确。这可能意味着最小化算法复杂性、最小化运行时间、最小化内存使用、最简单的实现或读取、最少的代码量等。
除非您有数千个条目,否则可能不值得优化您的数据结构或算法。社区公认的最佳做法是分析和优化整个程序的缓慢之处。
一个简单的实现无非就是加入列表并使用内置的sorted 对它们进行排序。例如,您可以考虑以下几个排序选项:
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)
输出
('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')
方法 1 - 将每个日期字符串解析为一个日期时间对象,对它们进行就地排序,并输出一个日期时间对象列表。
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)
输出
(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')
方法 2 - 使用动态解析日期的 lambda 函数对日期进行排序,并输出(新)字符串列表。
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)
输出
('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')
方法 3 - 使用 heapq.merge 更有效地排序。感谢@friendlydog 的建议。
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)
输出
(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')
注意事项:
- 我假设您输入字符串的格式是“日-月-年”。
- 我假设当同一个日期在多个列表中时,您希望按列表名称按字母数字顺序排序。
- 我将输出列表的格式留给读者作为练习。
- 这两个示例都在 Python 2 / 3 下运行。
在本例中,key 参数是一个 lambda。没有它,它将按字母顺序对字符串进行排序。这让我们可以覆盖它并按年 > 月 > 日排序。
更精细的实现可以利用对列表进行预排序的保证。维基百科有一个merge algorithms 列表供您考虑。