我有一个下面的词典列表:
listofdicts = [{'Time':2015-03-14 11:54:00, 'Value':'Some Value'},
{'Time':2015-03-14 13:23:00, 'Value':'Another Value'},
{'Time':2015-03-14 12:52:00, 'Value':'Some Value'}, ...]
我想在列表中搜索符合以下条件的词典: 查找三个或更多具有相同Value值的词典,其中Time值彼此相差10分钟。我希望这个算法在每个字典中创建一个符合此条件的新密钥,并将其标记为匹配。
e.g. The search algorithm would find:
{'Time':2015-03-14 11:54:00, 'Value':'Same Value'}
{'Time':2015-03-14 11:56:00, 'Value':'Same Value'}
{'Time':2015-03-14 11:52:00, 'Value':'Same Value'}
and add the matching key to each dictionary:
{'Time':2015-03-14 11:54:00, 'Value':'Same Value', 'Matching':'True'}
{'Time':2015-03-14 11:56:00, 'Value':'Same Value', 'Matching':'True'}
{'Time':2015-03-14 11:52:00, 'Value':'Same Value', 'Matching':'True'}
我已经创建了一个算法来执行此操作,但它不是特别有效或可扩展。是否有人能够就如何使其更好或研究领域提出任何建议?
当前算法:
for dict in listofdicts:
matchingdicts = []
for dict2 in listofdicts:
if dict['Value']==dict2['Value']:
matchingdicts.append(dict2)
listoftimeintervals =
[[dict['Time'] - datetime.timedelta(minutes=10),dict['Time']],
[dict['Time'] - datetime.timedelta(minutes=9),dict['Time'] + datetime.timedelta(minutes=1)],
...,
[dict['Time'],dict['Time'] + datetime.timedelta(minutes=10)]]
for time in listoftimeintervals:
dictsintimerange = []
for matchingdict in matchingdicts:
if time[0]<=matchingdict['Time']<=time[1]:
dictsintimerange.append(matchingdict)
if len(dictsintimerange)>=3:
for eachdict in dictsintimerange:
eachdict['Matching']=='True'
答案 0 :(得分:1)
(注意:我甚至没有通过解释器运行此代码。)
首先按值对dicts进行分区。
import collections
listofdictsbyvalue = collections.defaultdict(list)
for d in listofdicts:
listofdictsbyvalue[d['Value']].append(d)
然后按时间对每个列表进行排序并扫描。
import operator
k = 3
for lst in listofdictsbyvalue.values():
lst.sort(key=operator.itemgetter('Time'))
for i in range(len(lst) - (k - 1)):
if lst[i + (k - 1)]['Time'] - lst[i]['Time'] <= datetime.timedelta(minutes=10):
for j in range(i, i + k):
lst[j]['Matching'] = 'True'
答案 1 :(得分:0)
首先对列表进行排序,然后按顺序扫描,在10分钟内查找项目。 大致是:
ordered = sorted(listofdicts, key=lambda e:e['Time'])
for i,value in enumerate(ordered):
if value.get('Matching'):
continue
for j in range(i+2,len(order)):
if ordered[j]['Time'] - value['Time'] > timedelta(minutes=10):
break
if j-i>3:
for x in range(i,j):
ordered[x]['Matching']=True
对于排序,这应该是O(N lg N),对于比较,这应该是O(N)