![](/img/trans.png)
[英]Quickest way to get the min and max from a list of lists of lists in Python?
[英]How to create list of lists with min and max date from larger list?
我有一个由None
值分隔的周期列表,我需要创建一个列表列表,其中每个子列表包含相应周期的最小和最大日期。
例子:
import datetime
dates = [None, None, datetime.date(2018, 1, 11), datetime.date(2018, 3, 2), datetime.date(2018, 4, 30), datetime.date(2018, 5, 1), None, datetime.date(2018, 5, 30), datetime.date(2018, 6, 3), datetime.date(2018, 6, 4), None, None]
期望的输出:
[[datetime.date(2018, 1, 11), datetime.date(2018, 5, 1)],
[datetime.date(2018, 5, 30), datetime.date(2018, 6, 4)]]
我怎样才能做到这一点?
您可以使用itertools.groupby
( doc ) 将元素分组为None
和date
值,然后使用min()
、 max()
函数:
import datetime
dates = [None, None, datetime.date(2018, 1, 11), datetime.date(2018, 3, 2), datetime.date(2018, 4, 30), datetime.date(2018, 5, 1), None, datetime.date(2018, 5, 30), datetime.date(2018, 6, 3), datetime.date(2018, 6, 4), None, None]
from itertools import groupby
out = []
for v, g in groupby(dates, lambda k: k is None):
if v:
continue
l = [*g]
out.append([min(l), max(l)])
from pprint import pprint
pprint(out)
印刷:
[[datetime.date(2018, 1, 11), datetime.date(2018, 5, 1)],
[datetime.date(2018, 5, 30), datetime.date(2018, 6, 4)]]
编辑:感谢@BlackJack 的建议,这可以简化:
out = []
for v, g in groupby(dates, bool):
if v:
l = [*g]
out.append([min(l), max(l)])
这是我的看法。 此解决方案不需要任何额外的导入,并且在逻辑上对初学者友好。 以下是其工作原理的基础知识:
您迭代列表忽略前两个和最后一个None
值。
当您遇到列表中的第一个值或在None
您将最小值和最大值都设置为该值,因为这表示新时期的开始。
之后,对于您遇到的每个值,您将其与之前的最小值和最大值进行比较,并将其设置为新的最小值或最大值(如果更低或更高)。
一旦遇到None
您将当前的最小值和最大值保存到结果列表中并重置它们,因为这意味着新时期将从下一个值开始。
import datetime
dates = [None, None, datetime.date(2018, 1, 11), datetime.date(2018, 3, 2), datetime.date(2018, 4, 30),
datetime.date(2018, 5, 1), None, datetime.date(2018, 5, 30), datetime.date(2018, 6, 3),
datetime.date(2018, 6, 4), None, None]
min_date = None
max_date = None
result = []
for value in dates[2:-1]:
if value is None:
result.append([min_date, max_date])
min_date = None
max_date = None
elif min_date is None and max_date is None:
min_date = value
max_date = value
elif value < min_date:
min_date = value
elif value > max_date:
max_date = value
print(result)
输出:
[[datetime.date(2018, 1, 11), datetime.date(2018, 5, 1)], [datetime.date(2018, 5, 30), datetime.date(2018, 6, 4)]]
希望你从中学到了一些东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.