如果相同,则删除多维列表中的元组

时间:2018-11-19 09:59:52

标签: python tuples double list-comprehension

我有一个元组列表:

[[[('p', 'u'), ('r', 'w')], [('t', 'q')]], [[('p', 'u'), ('r', 'w')], [('v', 'q')]], [[('p', 'u'), ('r', 'w')], [('t', 's')]], [[('p', 'u'), ('r', 'w')], [('v', 's')]], [[('p', 'w'), ('r', 'u')], [('t', 'q')]], [[('p', 'w'), ('r', 'u')], [('v', 'q')]], [[('p', 'w'), ('r', 'u')], [('t', 's')]], [[('p', 'w'), ('r', 'u')], [('v', 's')]], [[('r', 'u'), ('p', 'w')], [('t', 'q')]], [[('r', 'u'), ('p', 'w')], [('v', 'q')]], [[('r', 'u'), ('p', 'w')], [('t', 's')]], [[('r', 'u'), ('p', 'w')], [('v', 's')]], **[[('r', 'w'), ('p', 'u')], [('t', 'q')]]**, [[('r', 'w'), ('p', 'u')], [('v', 'q')]], [[('r', 'w'), ('p', 'u')], [('t', 's')]], [[('r', 'w'), ('p', 'u')], [('v', 's')]]]

但是现在例如元素[[('p','u'),('r','w')], [('t','q')]]

[[('r','w'),('p','u')], [('t','q')]]相同,在列表中标记为 fat <​​/ strong>。

因此,在列表中,我有16个元素,其中每个元素都是双精度的。

现在,我要删除重复项,只剩下前八个元素。

天真,我尝试过

[[list(y) for y in set([tuple(set(x)) for x in doublegammas1])]]

但是在这里,他说:

TypeError: unhashable type: 'list'

所以我的问题:

如何扩展列表理解功能,使其适用于更多维的列表?

2 个答案:

答案 0 :(得分:2)

列表不可哈希,元组 可哈希。然后,您需要抽取set个这些元组。但是在这些元组中,您想忽略顺序。但是集合的元组不可哈希,因此您需要使用frozenset对象的元组:

uniques = {tuple(map(frozenset, i)) for i in doublegammas1}

print(uniques)

{(frozenset({('p', 'w'), ('r', 'u')}), frozenset({('t', 'q')})),
 (frozenset({('p', 'w'), ('r', 'u')}), frozenset({('v', 'q')})),
 (frozenset({('p', 'w'), ('r', 'u')}), frozenset({('v', 's')})),
 (frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 's')})),
 (frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 'q')})),
 (frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 'q')})),
 (frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 's')})),
 (frozenset({('p', 'w'), ('r', 'u')}), frozenset({('t', 's')}))}

然后您可以通过itertools unique_everseen recipe来应用此功能,该功能也可以在第三方库中以toolz.uniquemore_itertools.unique_everseen的形式使用:

from more_itertools import unique_everseen

def uniquekey(x):
    return tuple(map(frozenset, x))

res = list(unique_everseen(doublegammas1, key=uniquekey))

print(res)

[[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
 [[('p', 'u'), ('r', 'w')], [('v', 'q')]],
 [[('p', 'u'), ('r', 'w')], [('t', 's')]],
 [[('p', 'u'), ('r', 'w')], [('v', 's')]],
 [[('p', 'w'), ('r', 'u')], [('t', 'q')]],
 [[('p', 'w'), ('r', 'u')], [('v', 'q')]],
 [[('p', 'w'), ('r', 'u')], [('t', 's')]],
 [[('p', 'w'), ('r', 'u')], [('v', 's')]]]

输入数据

# input data
doublegammas1 = [[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
                 [[('p', 'u'), ('r', 'w')], [('v', 'q')]],
                 [[('p', 'u'), ('r', 'w')], [('t', 's')]],
                 [[('p', 'u'), ('r', 'w')], [('v', 's')]],
                 [[('p', 'w'), ('r', 'u')], [('t', 'q')]],
                 [[('p', 'w'), ('r', 'u')], [('v', 'q')]],
                 [[('p', 'w'), ('r', 'u')], [('t', 's')]],
                 [[('p', 'w'), ('r', 'u')], [('v', 's')]],
                 [[('r', 'u'), ('p', 'w')], [('t', 'q')]],
                 [[('r', 'u'), ('p', 'w')], [('v', 'q')]],
                 [[('r', 'u'), ('p', 'w')], [('t', 's')]],
                 [[('r', 'u'), ('p', 'w')], [('v', 's')]],
                 [[('r', 'w'), ('p', 'u')], [('t', 'q')]],
                 [[('r', 'w'), ('p', 'u')], [('v', 'q')]],
                 [[('r', 'w'), ('p', 'u')], [('t', 's')]],
                 [[('r', 'w'), ('p', 'u')], [('v', 's')]]]

答案 1 :(得分:1)

可变对象(例如列表或集合)不能是集合的成员。您可以使用不可变的冻结集。

main_list = [[[('p', 'u'), ('r', 'w')], [('t', 'q')]],
             [[('p', 'u'), ('r', 'w')], [('v', 'q')]],
             [[('p', 'u'), ('r', 'w')], [('t', 's')]],
             [[('p', 'u'), ('r', 'w')], [('v', 's')]],
             [[('p', 'w'), ('r', 'u')], [('t', 'q')]],
             [[('p', 'w'), ('r', 'u')], [('v', 'q')]],
             [[('p', 'w'), ('r', 'u')], [('t', 's')]],
             [[('p', 'w'), ('r', 'u')], [('v', 's')]],
             [[('r', 'u'), ('p', 'w')], [('t', 'q')]],
             [[('r', 'u'), ('p', 'w')], [('v', 'q')]],
             [[('r', 'u'), ('p', 'w')], [('t', 's')]],
             [[('r', 'u'), ('p', 'w')], [('v', 's')]],
             [[('r', 'w'), ('p', 'u')], [('t', 'q')]],
             [[('r', 'w'), ('p', 'u')], [('v', 'q')]],
             [[('r', 'w'), ('p', 'u')], [('t', 's')]],
             [[('r', 'w'), ('p', 'u')], [('v', 's')]]]

main_set = set(tuple(frozenset(innermost_list) for innermost_list in sublist) for sublist in main_list)

from pprint import pprint
pprint(main_set)

输出:

{(frozenset({('r', 'u'), ('p', 'w')}), frozenset({('t', 'q')})),
 (frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 'q')})),
 (frozenset({('r', 'u'), ('p', 'w')}), frozenset({('v', 'q')})),
 (frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 's')})),
 (frozenset({('r', 'u'), ('p', 'w')}), frozenset({('t', 's')})),
 (frozenset({('p', 'u'), ('r', 'w')}), frozenset({('v', 's')})),
 (frozenset({('r', 'u'), ('p', 'w')}), frozenset({('v', 's')})),
 (frozenset({('p', 'u'), ('r', 'w')}), frozenset({('t', 'q')}))}

要转换回嵌套列表的原始结构,请执行以下操作:

new_list = [[list(frozen) for frozen in subtuple] for subtuple in main_set]
pprint(new_list)

输出:

[[[('r', 'u'), ('p', 'w')], [('t', 'q')]],
 [[('p', 'u'), ('r', 'w')], [('v', 'q')]],
 [[('r', 'u'), ('p', 'w')], [('v', 'q')]],
 [[('p', 'u'), ('r', 'w')], [('t', 's')]],
 [[('r', 'u'), ('p', 'w')], [('t', 's')]],
 [[('p', 'u'), ('r', 'w')], [('v', 's')]],
 [[('r', 'u'), ('p', 'w')], [('v', 's')]],
 [[('p', 'u'), ('r', 'w')], [('t', 'q')]]]

更新:

一种从输入数据中删除重复项的解决方案。

unique = []

for item in main_list[:]:
    frozen_item = frozenset(frozenset(innermost_list) for innermost_list in item)
    if frozen_item not in unique:
        unique.append(frozen_item)
    else:
        main_list.remove(item)