在python字典中删除反向重复项

在python字典中删除反向重复项,python,dictionary,Python,Dictionary,我有一个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字典,其中包含一些示例键和值:

{'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']}

以下是一个解决方案,您可以将dict理解作为一行代码,将其放在一个循环中:

{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
这两种方法都假定您的dict名为
d

结果:

但是,我必须在此声明,您的文本描述不适合预期的示例。如果你能更新一下,那就太好了。
除此之外:您是否知道,您要求的算法完全依赖于顺序?在python 3.6之前,如果不明确使用有序dict,任何返回所需结果的解决方案都无法可靠地工作。

我不知道您的用例,但将相同的算法应用于例如倒序dict可以产生不同的结果吗

以下是一个解决方案,您可以将dict理解作为一行,将其放在一个循环中:

{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
这两种方法都假定您的dict名为
d

结果:

但是,我必须在此声明,您的文本描述不适合预期的示例。如果你能更新一下,那就太好了。
除此之外:您是否知道,您要求的算法完全依赖于顺序?在python 3.6之前,如果不明确使用有序dict,任何返回所需结果的解决方案都无法可靠地工作。

我不知道您的用例,但将相同的算法应用于例如倒序dict可以产生不同的结果吗

您可以将每个条目转换为
元组
,并使用
集合
获取
O(n)
时间

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']}

您可以将每个条目转换为
元组
,并使用
集合
获取
O(n)
时间

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']}
另一艘班轮:

>>> 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']}
内部dict是用排序后的元组
(key,value1,value2,…)
作为键和
(key,[value1,value2,…])
对作为值构建的。显然,对于每个已排序的元组,您都会保留最后一个
(key,[value])
对(只有当dict键已排序,Python>=3.6时,这才重要)。然后用这些
(key,[value])
对构建一个dict

如果只想获得第一个
键值(Python>=3.6),只需颠倒原始dict的迭代顺序:

>>> 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]]
因为第一个值是最后一个添加到dict并覆盖下一个(或以相反顺序覆盖上一个)的值。

另一行:

>>> 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']}
内部dict是用排序后的元组
(key,value1,value2,…)
作为键和
(key,[value1,value2,…])
对作为值构建的。显然,对于每个已排序的元组,您都会保留最后一个
(key,[value])
对(只有当dict键已排序,Python>=3.6时,这才重要)。然后用这些
(key,[value])
对构建一个dict

如果只想获得第一个
键值(Python>=3.6),只需颠倒原始dict的迭代顺序:

>>> 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]]

因为第一个值是最后一个添加到dict并覆盖下一个(或以相反顺序覆盖上一个)的值。

可以假定该值中没有重复项吗?所以
['b','b']
永远不会发生?@Error syntacticalreforse正确的是,永远不会有重复的键值。可以假定该值中没有重复的键值吗?所以
['b','b']
永远不会发生?@Error syntactical懊悔正确的是,永远不会有键值重复这不会造成只有
'x':['y']
不在
'x':['y']
'y':['x']
的情况。i,j,k集合也是如此。@MattEllen correct我只是专注于描述
'duplicate'键值组合
,而不是示例,这在我看来是不同的。@MattEllen编辑。奇怪的是,下院选民对编辑的反应有多快——他们是否还会回来,甚至记得这一点post@SpghttCd我删除了我的反对票和反对票。对不起,我是一个太快投否决票的罪魁祸首:p这不会造成只有
'x':['y']
仍然在
'x':['y']
'y':['x']
之外的情况。i,j,k集合也是如此。@MattEllen correct我只是专注于描述
'duplicate'键值组合
,而不是示例,这在我看来是不同的。@MattEllen编辑。奇怪的是,下院选民对编辑的反应有多快——他们是否还会回来,甚至记得这一点post@SpghttCd我删除了我的反对票和反对票。对不起,我是一个罪魁祸首,因为我太快而投了反对票:P