Skip to main content
 首页 » 编程设计

python之返回缺失值列表

2025年05月04日28Renyi-Fan

以下行生成现有数据点的列表:

datapoint_list = organisation.datapoint_set.filter(timestamp__gte=startDate, timestamp__lte=endDate) 

我想以 JSON 格式返回从 startDate 到 lastDate 的日期,没有现有数据点。

如何做到这一点?

我最好的想法是:

class Missing(generics.ListAPIView) 
    ... 
    queryset = organisation.datapoint_set.filter(timestamp__gte=startDate, timestamp__lte=endDate) 
 
    Loop over the datesdelta 
        Loop over the datapoints 
            If datapoint.timestamp == datedelta.timestamp then 
                Push timestamp to object 
                Continue 
            End if 
        End loop 
    End loop 
    Return object 

但是我没有成功循环日期。也许还有更简单的方法来做到这一点?

编辑:

datesdelta 由查询参数确定,默认情况下应查找上周丢失的数据点:

    days = int(self.request.query_params.get('days', 7)) 
    startDate = datetime.today() - timedelta(days) 
    endDate = datetime.today() 

查询集包含:

<DataPoint: Value: 123, Timestamp: 2015-12-15> 
<DataPoint: Value: 123, Timestamp: 2015-12-11> 
<DataPoint: Value: 123, Timestamp: 2015-12-10> 
<DataPoint: Value: 123, Timestamp: 2015-12-09> 
<DataPoint: Value: 123, Timestamp: 2015-12-08> 

JSON 输出应该类似于

[ 
    'date': '2015-12-16', 
    'date': '2015-12-14', 
    'date': '2015-12-13', 
    'date': '2015-12-12', 
    'date': '2015-11-07' 
} 

我的问题是如何从该查询集获取该输出。

请您参考如下方法:

set() 学会使用它,您将统治世界!首先,根据您展示的示例对您的查询进行轻微修改,您只需要日期,以便让查询更高效:

queryset = organisation.datapoint_set.filter(timestamp__gte=startDate, timestamp__lte=endDate).values_list('timestamp', flat=True) 

完成,这看起来像这样:

queryset = [datetime(2015,12,15), datetime(2015,12,11), datetime(2015,12,10), datetime(2015,12,9), datetime(2015,12,8)] 

现在我们生成我们想要的值:

>>> set([endDate - timedelta(x) for x in xrange(days)]) 
set([datetime.date(2015, 12, 14), datetime.date(2015, 12, 16), datetime.date(2015, 12, 15), datetime.date(2015, 12, 12), datetime.date(2015, 12, 13), datetime.date(2015, 12, 10), datetime.date(2015, 12, 11)]) 

完美,我们(减去它们)-:

>>> set([endDate - timedelta(x) for x in xrange(days)]) - set(queryset) 
set([datetime.date(2015, 12, 14), datetime.date(2015, 12, 16), datetime.date(2015, 12, 15), datetime.date(2015, 12, 12), datetime.date(2015, 12, 13), datetime.date(2015, 12, 10), datetime.date(2015, 12, 11)]) 

让一切变得漂亮:

import datetime 
days = 10 
# a bit of a hack to get the current date without any time stuff. 
endDate = datetime.datetime.combine(datetime.date.today(), datetime.datetime.min.time()) 
queryset = [datetime.datetime(2015,12,15), datetime.datetime(2015,12,11), datetime.datetime(2015,12,10), datetime.datetime(2015,12,9), datetime.datetime(2015,12,8)] 
date_ranges = set([endDate - datetime.timedelta(x) for x in xrange(days)]) 
output = sorted(list(date_ranges - set(queryset))) 
print([x.strftime('%Y-%m-%d') for x in output]) 

输出是:

['2015-12-07', '2015-12-12', '2015-12-13', '2015-12-14', '2015-12-16'] 

如果您将时间戳记为 date 对象,则更容易:

import datetime 
days = 10 
endDate = datetime.date.today() 
queryset = [datetime.date(2015,12,15), datetime.date(2015,12,11), datetime.date(2015,12,10), datetime.date(2015,12,9), datetime.date(2015,12,8)] 
date_ranges = set([endDate - datetime.timedelta(x) for x in xrange(days)]) 
output = sorted(list(date_ranges - set(queryset))) 
print([x.strftime('%Y-%m-%d') for x in output])