基于两个属性深度过滤字典列表

时间:2017-12-07 19:35:19

标签: python

我正在努力寻找一种有效的方法来处理这个问题。我有一个超过400k条目的词典列表。我需要首先找到共享共同密钥的所有条目,让我们说该列表中的“pallet-id”然后从该子列表中验证所有这些共享相同的“位置”密钥。我只想从初始列表中获得具有类似“托盘ID”的条目,但前提是其中一个条目的“位置”与其他条目不同。

实施例

这将与托盘ID 123456一起使用

entry1 = {'location': 'LOC1', 'pallet-id': '123456', ...}  
entry2 = {'location': 'LOC1', 'pallet-id': '123456', ...}  
entry3 = {'location': 'LOC1', 'pallet-id': '123456', ...}  
entry4 = {'location': 'LOC1', 'pallet-id': '123456', ...} 

由于所有人共享同一地点,我不关心这一点。

这将与pallet-id 5555一起使用

entry1 = {'location': 'LOC1', 'pallet-id': '5555', ...}  
entry2 = {'location': 'LOC1', 'pallet-id': '5555', ...}  
entry3 = {'location': 'LOC2', 'pallet-id': '5555', ...}  
entry4 = {'location': 'LOC1', 'pallet-id': '5555', ...}  

在这种情况下,由于我有一个不同的位置,我想存储这4个条目。

我遇到的问题是报告花了无数的时间只检查每个托盘ID,然后在初始列表中查找相同托盘ID的其余部分,是否有更有效的方法处理这个?

1 个答案:

答案 0 :(得分:1)

嵌套循环在这里是个坏主意,因为它会导致二次时间复杂度。你可以在线性时间内完成:

from collections import Counter
from operator import itemgetter

pal = itemgetter('pallet-id')
pal_loc = itemgetter('pallet-id', 'location')

# unique pallet-id, location combos
pallocs = set(map(pal_loc, entries))
# set([('5555', 'LOC1'), ('5555', 'LOC2'), ('123456', 'LOC1')])

# count pallet-id occurrences in the unique combos
count = Counter(pl[0] for pl in pallocs) 
# Counter({'5555': 2, '123456': 1})

# filter the entries for pallet-ids with counts greater than 1
filtered_entries = [e for e in entries if count[pal(e)] > 1]