Python 3 中使用字典维护时间限制事件查找

51 阅读2分钟

事件数据是一种不断更新的数据,例如 USGS 地震数据。USGS 提供了过去一小时或一天内所有地震的列表,并每隔几分钟更新一次该列表。我们希望每分钟轮询该列表,对列表中的新事件进行操作,同时忽略已处理的事件。

一个简单的方式是使用列表来存储新事件:

events = list()
for f in features:

    event = [{
        'name': 'usgs.earthquake.feature', # Time Series Name
        'columns': ['id', 'long', 'lat', 'depth', 'mag', 'type'\
                    'magtype', 'tz', 'felt', 'place', 'status'\
                    'gap', 'dmin', 'rms', 'ids', 'title', 'types'\
                    'cdi', 'net', 'nst', 'sources', 'alert', 'time'\
                    'tsunami', 'code', 'sig'
                    ], # Keys
        'points': [[ f['id'],\
                     f['geometry']['coordinates'][0],\
                     f['geometry']['coordinates'][1],\
                     f['geometry']['coordinates'][2],\
                     f['properties']['mag'],\
                     f['properties']['type'],\
                     f['properties']['magType'],\
                     f['properties']['tz'],\
                     ...
                     f['properties']['time'],\
                     f['properties']['tsunami'],\
                     f['properties']['code'],\
                     f['properties']['sig']
                      ]] # Data points
    }]

    if event in events:
        log.debug('Surpressing duplicate event id: %s', event[0]['points'][0][0])
    else:
        log.debug('Event data: %s', event)

        events.insert(0, event)

        handler.postEvent(event)

    log.debug('Event Cache Count: %s', len(events))

但是,这种方法存在以下问题:

  • 随着时间的推移,列表会变得非常长,查找新事件的效率会降低。
  • 难以维护过去一段时间内的数据,例如过去 2 小时或 36 小时。
  1. 解决方案

更好的方法是使用字典来存储事件数据。字典的键是事件的 ID,值是事件的数据。这样,我们就可以快速地查找事件,并轻松地维护过去一段时间内的数据。

events = {}
for f in features:

    event = [{
        'name': 'usgs.earthquake.feature', # Time Series Name
        'columns': ['id', 'long', 'lat', 'depth', 'mag', 'type'\
                    'magtype', 'tz', 'felt', 'place', 'status'\
                    'gap', 'dmin', 'rms', 'ids', 'title', 'types'\
                    'cdi', 'net', 'nst', 'sources', 'alert', 'time'\
                    'tsunami', 'code', 'sig'
                    ], # Keys
        'points': [[ f['id'],\
                     f['geometry']['coordinates'][0],\
                     f['geometry']['coordinates'][1],\
                     f['geometry']['coordinates'][2],\
                     f['properties']['mag'],\
                     f['properties']['type'],\
                     f['properties']['magType'],\
                     f['properties']['tz'],\
                     ...
                     f['properties']['time'],\
                     f['properties']['tsunami'],\
                     f['properties']['code'],\
                     f['properties']['sig']
                      ]] # Data points
    }]

    eventid = event[0]['points'][0][0]

    if eventid in events:
        log.debug('Surpressing duplicate event id: %s', eventid)
    else:
        log.debug('Event data: %s', event)

        events[eventid] = event

        handler.postEvent(event)

    log.debug('Event Cache Count: %s', len(events))

为了维护过去一段时间内的数据,我们可以使用以下代码:

import datetime

# 获取当前时间
now = datetime.datetime.utcnow()

# 设置时间限制为 2 小时
time_limit = datetime.timedelta(minutes=120)

# 遍历事件字典
for eventid, event_data in events.items():

    # 获取事件时间
    event_time = event_data[0]['points'][0][17]

    # 计算时间差
    time_diff = now - event_time

    # 如果时间差大于时间限制,则删除事件
    if time_diff > time_limit:
        del events[eventid]

这种方法可以有效地维护过去一段时间内的数据,并快速地查找新事件。