我正在编写一个Python函数,用于从排序列表中挑选出具有特定范围内的日期戳的对象。用户提供开始和结束日期。如果他们想分别使用列表的开始/结束日期作为开始/结束日期,则可以将它们中的任何一个留空。如果用户提供日期,则可以选择是包含还是排除日期。目前,我的函数如下所示:
def get_items_in_date_range(all_items, start_date=None, end_date=None,
include_start_date=True, include_end_date=True):
items_in_date = []
for item in all_items:
if start_date and end_date:
if include_start_date and include_end_date:
if start_date <= item.date_stamp <= end_date: #
items_in_date.append(item)
elif include_start_date:
if start_date <= item.date_stamp < end_date: #
items_in_date.append(item)
elif include_end_date:
if start_date < item.date_stamp <= end_date: #
items_in_date.append(item)
else:
if start_date < item.date_stamp < end_date: #
items_in_date.append(item)
...
(如果有帮助,我可以发布函数的其余部分,但它是相同的几个if
语句,针对缺少start_date
和end_date
进行了调整)。
我的问题是:有没有办法准备标有#
符号的if
语句,以便代码可以稍微压缩一下?也许在某种程度上类似于Python字符串格式,例如
if start_date %op item.date_stamp %op end_date % (op1, op2):
我可以在其中分配op1
和op2
在函数开始时<
或<=
。
这是我提交的第一个问题,所以如果我可以提供任何其他信息来帮助/澄清,请告诉我。谢谢!
Python 运算符可作为内置operator
包中的方法使用。
还可以通过先筛选所有项
这给出了这样的东西(未经测试):
import operator
def get_items_in_date_range(all_items, start_date=None, end_date=None,
include_start_date=True, include_end_date=True):
start_op = operator.ge if include_start_date else operator.gt
end_op = operator.le if include_end_date else operator.lt
filtered_items = all_items
if start_date:
filtered_items = [item for item in filtered_items if start_op(item, start_date)]
if end_date:
filtered_items = [item for item in filtered_items if end_op(item, end_date)]
return filtered_items
消除所有不同比较的需要的一种方法是在函数的开头设置开始和结束日期,然后只执行一次比较。
您可以将开始日期和结束日期保留为特殊情况,也可以像肉豆蔻64那样调整它们以适应比较。
def get_items_in_date_range(all_items, start_date=None, end_date=None,
include_start_date=True, include_end_date=True):
if start_date is None:
start_date = MIN_DATE
if end_date is None:
end_date = MAX_DATE
items_in_date = []
for item in all_items:
is_in_range = start_date < item < end_date
is_start = include_start_date and item == start_date
is_end = include_end_date and item == end_date
if is_in_range or is_start or is_end:
item_in_date.append(item)
通常没有办法生成Python代码(除非不同的Python脚本将其写入文件并且有点复杂)。
在这种情况下,您可以执行以下操作:
if include_start_date:
start_date - 1 # assuming you know how to subtract a day from the date
if include_end_date:
end_date + 1 # assuming you know how to add a day to the date
for item in all_items:
if start_date < item.date_stamp < end_date:
items_in_date.append(item)
您可以使用运算符模块解决此问题:
import operator
def get_items_in_date_range(all_items, start_date=None, end_date=None,
include_start_date=True, include_end_date=True):
lower_op = operator.lte if include_start_date else operator.lt
upper_op = operator.lte if include_end_date else operator.lt
if start_date is None:
start_date = <something-really-in-the-past>
if end_date is None:
end_date = <something-nearing-the-universe-entropy-death>
...