如何摆脱列表中的反向元组?

时间:2018-11-23 16:17:09

标签: python list dictionary tuples

例如,假设我有一个列表:

list_ = [(4,5),(5,4),(5,4),(8,10),(10,8),(9,3),(5,4),(10,8),(8,8)]

如何去除所有反向元组,所以剩下的是:

list_ = [(4,5),(8,10),(9,3),(8,8)] 

这是我正在做的一个个人项目,我写了一些东西来检测反向元组并删除它们,但是只删除其中一个反向元组(而不是全部)。我认为字典在这里很有用,但不确定如何实现它

3 个答案:

答案 0 :(得分:4)

我会写一个很好的老式for循环。该解决方案保证了以下几点:保留任何反向元组的第一个,输出列表与输入的顺序相同,不对输入元组的长度做任何假设。

list_ = [(4,5),(5,4),(5,4),(8,10),(10,8),(9,3),(5,4),(10,8),(8,8)]

output, seen = [], set()
for item in list_:
    t1 = tuple(item)
    if t1 not in seen and tuple(reversed(item)) not in seen:
        seen.add(t1)
        output.append(item)

print(output)
# [(4, 5), (8, 10), (9, 3), (8, 8)]

答案 1 :(得分:3)

长度为2的组合

对于所有长度为2的元组,您可以将frozenset与文档中的itertools unique_everseen recipe结合使用,more_itertoolstoolz第三方库中也提供这些功能:

from more_itertools import unique_everseen

list_ = [(4,5),(5,4),(5,4),(8,10),(10,8),(9,3),(5,4),(10,8),(8,8)]

res = list(unique_everseen(list_, key=frozenset))

[(4, 5), (8, 10), (9, 3), (8, 8)]

frozenset是唯一项的无序但可哈希的集合。该解决方案假定您所有输入的长度均为2。因此,不会区分(8,)(8, 8)

长度可变的一对

对于不同长度的元组,您可以对配方进行一些小的调整:

def unique_everseen_custom(it):
    seen = set()
    seen_add = seen.add
    for tup in it:
        if (tup not in seen) and (tup[::-1] not in seen):
            seen_add(tup)
            seen_add(tup[::-1])
            yield tup

res = list(unique_everseen_custom(list_))

答案 2 :(得分:2)

如果我们认为您所有的元组都是duplet,并且您想要保留唯一值:

list_ = [(4,5),(5,4),(5,4),(8,10),(10,8),(3,9),(5,4)]

然后我们对元组进行排序:

list_ = [tuple(sorted(t)) for t in list_]

然后使用一组删除重复项:

list_ = list(set(list_))