在Python中删除字典值中的重复项

4
抱歉,这个主题的标题比较模糊,我很难解释清楚。
我有一个字典,其中每个值都是一个项目列表。我希望删除重复的项目,使得每个项目在列表中最少出现一次(最好只出现一次)。
请考虑以下字典:
example_dictionary = {"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3]}

'weapon2'和'weapon3'具有相同的值,因此应该得到:

result_dictionary = {"weapon1":[1],"weapon2":[3],"weapon3":[2]}

由于我不在意顺序,这也会导致以下结果:

result_dictionary = {"weapon1":[1],"weapon2":[2],"weapon3":[3]}

但是当“没有选择”时,它应该保留值。考虑这个新字典:

example_dictionary = {"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3],"weapon4":[3]}

现在,由于无法仅在不留下键为空的情况下分配'2'或'3',因此可能的输出如下:

result_dictionary = {"weapon1":[1],"weapon2":[3],"weapon3":[2],"weapon4":[3]}

我可以简化问题,只处理第一部分并进行管理,但我更喜欢解决这两个部分的方案。


你能解释一下为什么weapon1的结果中有[1]吗?而weapon2和weapon3会从第一个weapon1 [1,2,3] 中获取值吗? - Aaditya Ura
@AyodhyankitPaul weapon1 是唯一在其列表中拥有[1]的武器,这就是为什么它拥有[1]。weapon2和weapon3都具有[2, 3],因此每个都获得一个独立的数字,其中一个获得[2],另一个获得[3]。 - L.S
3个回答

1
#!/usr/bin/env python3

example_dictionary = {"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3]}

result = {}
used_values = []

def extract_semi_unique_value(my_list):
    for val in my_list:
        if val not in used_values:
            used_values.append(val)
            return val
    return my_list[0]

for key, value in example_dictionary.items():
    semi_unique_value = extract_semi_unique_value(value)
    result[key] = [semi_unique_value]

print(result)

1
这种情况下不适用,例如 {'weaponA': [1, 2], 'weaponB': [1]} - SCB
完全独一无二并不是一个限制条件。如果我正确理解问题,那么这种情况将会给出[1]和[1],这是可以接受的。 - Harald Nordgren
如果可能的话,我宁愿得到[1]和[2],而不会使它过于复杂,因为输入的大小可能很大。 - L.S

0

这可能不是最有效的解决方案。因为它涉及到对所有可能的组合进行迭代,所以对于大目标来说运行速度会相当慢。

它利用 itertools.product() 来获取所有可能的组合。然后在其中,尝试找到具有最多唯一数字的组合(通过测试集合的长度来实现)。

from itertools import product
def dedup(weapons):
    # get the keys and values ordered so we can join them back
    #  up again at the end
    keys, vals = zip(*weapons.items())

    # because sets remove all duplicates, whichever combo has
    #  the longest set is the most unique
    best = max(product(*vals), key=lambda combo: len(set(combo)))

    # combine the keys and whatever we found was the best combo
    return {k: [v] for k, v in zip(keys, best)}

从这些例子中:

dedup({"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3]})
#: {'weapon1': 1, 'weapon2': 2, 'weapon3': 3}
dedup({"weapon1":[1,2,3],"weapon2":[2,3],"weapon3":[2,3],"weapon4":[3]})
#: {'weapon1': 1, 'weapon2': 2, 'weapon3': 2, 'weapon4': 3}

0

这可能会有所帮助

import itertools
res = {'weapon1': [1, 2, 3], 'weapon2': [2, 3], 'weapon3': [2, 3]}
r = [[x] for x in list(set(list(itertools.chain.from_iterable(res.values()))))]
r2 = [x for x in res.keys()]
r3 = list(itertools.product(r2,r))
r4 = dict([r3[x] for x in range(0,len(r3)) if not x%4])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接