[英]Python intersection of 2 lists of dictionaries
我有 2 個 dicts 列表,例如
list1 = [{'count': 351, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'},
{'count': 332, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'},
{'count': 336, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'},
{'count': 359, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'},
{'count': 309, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'}]
list2 = [{'count': 359, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'},
{'count': 351, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'},
{'count': 381, 'evt_datetime': datetime.datetime(2015, 10, 22, 8, 45), 'att_value': 'red'}]
我正在嘗試從兩個列表中獲取常見的字典。 我想要的輸出是字典的鍵和值的精確匹配。
[{'count': 359, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'},
{'count': 351, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'}]
這可以由python本身有效地完成還是需要像pandas這樣的lib?
使用列表理解:
[x for x in list1 if x in list2]
這將返回我的數據列表:
[{'count': 351, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'}, {'count': 359, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'}]
對於大型列表,下面的解決方案可能會表現得更好,但由於排序步驟,也可能需要更多內存。
交集可以通過定義的 sortKey 完成,例如“count”,或者按照https://stackoverflow.com/a/60765557/1497139 的建議使用字典的哈希值。 該算法對兩個列表進行排序,並並行迭代檢查兩個迭代器的三種可能狀態:
在給定的示例中,使用“count”字段作為 sortKey 的結果與使用 dict 哈希作為鍵的結果相同。
[{'count': 351, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'}, {'count': 359, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'}]
[{'count': 351, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'}, {'count': 359, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'}]
python單元測試
def testIntersection(self):
'''
test creating the intersection of a list of dictionaries
'''
list1 = [{'count': 351, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'},
{'count': 332, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'},
{'count': 336, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'},
{'count': 359, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'},
{'count': 309, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'}]
list2 = [{'count': 359, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'},
{'count': 351, 'evt_datetime': datetime.datetime(2015, 10, 23, 8, 45), 'att_value': 'red'},
{'count': 381, 'evt_datetime': datetime.datetime(2015, 10, 22, 8, 45), 'att_value': 'red'}]
listi=ListOfDict.intersect(list1, list2,'count')
print(listi)
self.assertEquals(2,len(listi))
listi=ListOfDict.intersect(list1, list2)
print(listi)
self.assertEquals(2,len(listi))
字典列表
'''
Created on 2020-08-11
@author: wf
'''
class ListOfDict(object):
'''
https://stackoverflow.com/questions/33542997/python-intersection-of-2-lists-of-dictionaries/33543164
'''
@staticmethod
def sortKey(d,key=None):
''' get the sort key for the given dict d with the given key
'''
if key is None:
# https://stackoverflow.com/a/60765557/1497139
return hash(tuple(d.items()))
else:
return d[key]
@staticmethod
def intersect(listOfDict1,listOfDict2,key=None):
'''
get the intersection lf the two lists of Dicts by the given key
'''
i1=iter(sorted(listOfDict1, key=lambda k: ListOfDict.sortKey(k, key)))
i2=iter(sorted(listOfDict2, key=lambda k: ListOfDict.sortKey(k, key)))
c1=next(i1)
c2=next(i2)
lr=[]
while True:
try:
val1=ListOfDict.sortKey(c1,key)
val2=ListOfDict.sortKey(c2,key)
if val1<val2:
c1=next(i1)
elif val1>val2:
c2=next(i2)
else:
lr.append(c1)
c1=next(i1)
c2=next(i2)
except StopIteration:
break
return lr
如果順序不重要並且您不需要擔心重復,那么您可以使用集合交集:
a = [1,2,3,4,5]
b = [1,3,5,6]
list(set(a) & set(b))
[1, 3, 5]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.