字典列表的差异

问题描述 投票:0回答:3

我已经搜索了很多东西,但是还没有找到与此类似的问题。

我有两个以下格式的字典列表:

data1 = [
    {'id': 4, 'date_time': datetime.datetime(2020, 4, 3, 12, 34, 40)},
    {'id': 4, 'date_time': datetime.datetime(2020, 4, 3, 12, 34, 40)},
    {'id': 6, 'date_time': datetime.datetime(2020, 4, 3, 12, 34, 40)},
    {'id': 7, 'date_time': datetime.datetime(2020, 4, 3, 16, 14, 21)},
]

data2 = [
    {'id': 4, 'date_time': datetime.datetime(2020, 4, 3, 12, 34, 40)},
    {'id': 6, 'date_time': datetime.datetime(2020, 4, 3, 12, 34, 40)},
]

所需输出:

final_data = [
    {'id': 4, 'date_time': datetime.datetime(2020, 4, 3, 12, 34, 40)},
    {'id': 7, 'date_time': datetime.datetime(2020, 4, 3, 16, 14, 21)},
]

我只需要data1中的字典,而不是data2中的字典。

直到现在,当我在两个for循环中找到一个匹配项时,我将字典从列表中弹出,但这对我来说似乎不是一个好方法。如何获得所需的输出?

不必省时,因为每个列表中最多有数十个词典


当前实施:
counter_i = 0

for i in range(len(data1)):
    counter_j = 0
    for j in range(len(data2)):
        if data1[i-counter_i]['id'] == data2[j-counter_j]['id'] and data1[i-counter_i]['date_time'] == data2[j-counter_j]['date_time']
            data1.pop(i-counter_i)
            data2.pop(j-counter_j)
            counter_i += 1 
            counter_j += 1 
            break
python list algorithm dictionary difference
3个回答
2
投票

如果性能不是问题,为什么不这样做:

for d in data2:
    try:
        data1.remove(d)
    except ValueError:
        pass  

list.remove检查对象是否相等,而不是同一性,因此适用于具有相同键和值的字典。另外,list.remove一次仅删除一个事件。


1
投票

schwobaseggl的答案可能是最干净的解决方案(如果需要保持data1完整,只需在删除之前进行复制)。

但是,如果您要使用集合差异...好的字典是不可哈希的,因为其基础数据可能会更改并导致问题(同样的原因,列表或集合也不可哈希)。>>

但是,您可以在冻结集中获取所有字典对以表示字典。另外,frozenset是可散列的,因此您可以将它们添加到集合中,这与do set normal set有差异。并在最后重建字典:D。

我实际上不建议这样做,但是我们开始:

final_data = [
  dict(s)
  for s in set(
    frozenset(d.items()) for d in data1
  ).difference(
    frozenset(d.items()) for d in data2
  )
]

-1
投票

您可以采用任何一种方式:

© www.soinside.com 2019 - 2024. All rights reserved.