我有一个字典,其文件名为1.xml,然后是DeviceID,如3和12.
{'1.xml': ['3', '12'], '2.xml': ['23', '17''], '3.xml': ['1', '12']}
我有一个代码可以比较DeviceID并在有重复项时显示。现在它只适用于所有文件都包含DeviceID的情况。 运行此代码时:
it = iter(dict.values())
intersection = set(next(it))
print(intersection)
for vals in it:
intersection &= set(vals)
它返回
set()
因为DeviceID仅在第一个和第三个文件中,但不在第二个文件中。有人可以帮我修改这段代码,让它在某些文件中只有重复时显示DeviceID吗?
答案 0 :(得分:3)
当字典中的新值不包含它们时,set
交集会丢弃所有先前的重复项。因此,您可以使用 multiset - collections.Counter
代替set
来计算每个 DeviceID 出现在其中的次数。 filename-deviceid 字典:
from collections import Counter
d = {'1.xml': ['3', '12'], '2.xml': ['23', '17'], '3.xml': ['1', '12']}
c = Counter(i for val in d.values() for i in val)
print(c)
# Counter({'12': 2, '1': 1, '17': 1, '23': 1, '3': 1})
print(c.most_common(1))
# [('12', 2)]
如果您有大量商品,并且您不确定将哪个号码传递给most_common
以获取重复的ID,那么您可以使用:
dupe_ids = [id for id, count in c.items() if count > 1]
答案 1 :(得分:1)
摩西发布的答案是代码行数较少,但这可以更直接地解决您的问题,并且可能表现更好,具体取决于数据集:
你的代码不起作用的原因是因为而不是&
将交叉点放在一起,你实际上想要取得所有交叉点的联合。您的代码的以下更新说明了如何执行此操作:
dev_ids = {'1.xml': ['3', '12'], '2.xml': ['23', '17'], '3.xml': ['1', '12']}
it = iter(dev_ids.values())
all_ids = set(next(it))
dups = set()
for vals in it:
vals_set = set(vals)
dups.update(all_ids.intersection(vals_set))
all_ids.update(vals_set)
print(dups)
正如您所看到的,我们将所有ID累积到一个集合中 - .update()
本质上是一个就地联合操作 - 并在我们去的时候对它执行交叉。每个交叉点可以被认为是该文件中包含的“重复”。我们将重复项累积到变量dup
中,这就成了我们的答案。