删除字典Python中的反向重复项

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

我有一个 python 字典,其中包含一些示例键和值:

{'a': ['b'],
 'c': ['d'],
 'x': ['y'],
 'y': ['x'],
 'i': ['j','k'],
 'j': ['i','k']
 'k': ['i','j']}

键是什么字母以及值是哪个字母是无关紧要的,只要它们被证明有关系。我需要能够删除任何“重复”键值组合,以便我的字典显示如下。

{'a': ['b'],
 'c': ['d'],
 'x': ['y'],
'i': ['j','k']}
python dictionary
3个回答
3
投票

您可以将每个条目转换为排序的

tuple
并使用
set
来获取
O(d * vlog(v) )
时间,其中
d
是字典中键的数量,
v
是值的长度。
vlog(v
用于对每行需要完成的元组进行排序。

d = {'a': ['b'],
 'c': ['d'],
 'x': ['y'],
 'y': ['x'],
 'i': ['j','k'],
 'j': ['i','k'],
 'k': ['i','j']}

seen = set()
to_remove = []
for key, val in d.items():
    entry = tuple(sorted(val.copy() + [key]))
    to_remove.append(key) if entry in seen else seen.add(entry)

for key in to_remove:
    del d[key]
print(d)

输出:

{'a': ['b'], 'c': ['d'], 'x': ['y'], 'i': ['j', 'k']}

0
投票

这是一种解决方案,如何将它放在一个循环中,并将字典理解作为单行:

{k: v for i, (k, v) in enumerate(d.items()) if not set(list(d.keys())[:i]).intersection(v)}

如果你想很快得到它:

s = set()
dmod = {}
for k, v in d.items():
    s.add(k)
    if not s.intersection(v):
        dmod[k] = v

两种方法都假设你的字典名为

d

结果:

# {'a': ['b'], 'c': ['d'], 'x': ['y'], 'i': ['j', 'k']}

但是,我必须在这里声明,您的文字描述不符合预期的示例。如果能更新一下就好了
除此之外:您是否知道您要求的算法完全依赖于顺序?在 python 3.6 之前,如果不明确使用有序字典,没有任何解决方案可以返回您想要的结果可靠地工作。
我不知道你的用例,但是将相同的算法应用于例如可以吗?向后排序的字典会产生不同的结果吗?


0
投票

另一内衬:

>>> d = {'a': ['b'], 'c': ['d'], 'x': ['y'], 'y': ['x'], 'i': ['j','k'], 'j': ['i','k'], 'k': ['i','j']}
>>> dict({tuple(sorted((k, *v))):(k, v) for k, v in d.items()}.values())
{'a': ['b'], 'c': ['d'], 'y': ['x'], 'k': ['i', 'j']}

内部字典是用sorted元组

(key, value1, value2, ...)
作为键和
(key, [value1, value2, ...])
对作为值构建的。显然,对于每个排序的元组,您保留最后一个
(key, [value])
对(仅当 dict 键已排序时这才重要,Python >= 3.6)。然后用这些
(key, [value])
对构建一个字典。

如果只想获取第一个

key-value
(Python >= 3.6),只需颠倒原始字典的迭代顺序即可:

>>> dict({tuple(sorted((k, *v))):(k, v) for k, v in sorted(d.items(), reverse=True)}.values())
{'x': ['y'], 'i': ['j', 'k'], 'c': ['d'], 'a': ['b']}

如果还不清楚,这里有一个更简单的例子。我想在列表中保留具有给定长度的第一个列表:

>>> L = [[1], [2], [1,2], [2,3,4], [3], [5,2], [7,8,9]]
>>> {len(v): v for v in reversed(L)}
{3: [2, 3, 4], 2: [1, 2], 1: [1]}

我们看到只保留了第一个值:

[*[1]*, [2], *[1,2]*, *[2,3,4]*, [3], [5,2], [7,8,9]]

因为第一个值是最后一个添加到字典中的值,并覆盖下一个值(或按相反顺序覆盖前一个值)。

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