Python: 删除列表和子列表中的重复元素;如果有重复则删除整个子列表

3

在Python 2.7中,是否有任何函数或方法可以递归地实现这一点?

Input : ['and', ['or', 'P', '-R', 'P'], ['or', '-Q', '-R', 'P']]
Output : ['and', ['or', 'P', '-R'], ['or', '-Q', '-R', 'P']]

在sublist1中删除重复的'P'作为重复项

Input : ['and', ['or', 'P', '-R', 'P'], ['or', '-Q', '-R', 'P'], ['or', 'P', '-R', 'P']]
Output : ['and', ['or', 'P', '-R'], ['or', '-Q', '-R', 'P']]

将子列表1中的重复出现的“P”也视为重复项删除,并删除子列表3作为子列表1的重复项。

谢谢

3个回答

2
您可以使用set和生成器表达式将内部列表转换为元组,元组是不可变对象,然后在其上应用set
>>> a=['and', ['or', 'P', '-R', 'P'], ['or', '-Q', '-R', 'P'], ['or', 'P', '-R', 'P']]
>>> set(tuple(p) if isinstance(p,set) else p for p in (set(i) if isinstance(i,list) or isinstance(i,tuple) else i for i in a))
set(['and', ('P', 'or', '-R'), ('P', '-Q', 'or', '-R')])

输出仍然包含重复的“P”。我们能否做些什么来保留子列表或项目的顺序? - skool99
你的输出仍然包含重复的“P”。而且我尝试了你的逻辑,子列表的顺序也改变了。我们能做些什么来保留子列表或项目的顺序吗? - skool99
有没有其他的方法可以做到这一点? - skool99
@SandeepKulkarni 对不起,我错过了那个简单的点!我编辑了代码 ;) - Mazdak

2

我认为您需要创建一个自定义的移除重复项函数,以保留子列表的顺序。试试这个方法:

def rem_dup(lis):
    y, s = [], set()
    for t in lis:
        w = tuple(sorted(t)) if isinstance(t, list) else t
        if not w in s:
            y.append(t)
            s.add(w)
    return y

inp = ['and', ['or', 'P', '-R', 'P'], ['or', '-Q', '-R', 'P'], ['or', 'P', '-R', 'P']]

out = [rem_dup(i) if isinstance(i, list) else i for i in rem_dup(inp)] 

>>>out
['and', ['or', 'P', '-R'], ['or', '-Q', '-R', 'P']]

1
你可以使用 OrderedDict 来去重并保持顺序:
from collections import OrderedDict
inp= ['and', ['or', 'P', '-R', 'P'], ['or', '-Q', '-R', 'P']]

out = [OrderedDict.fromkeys(sub).keys() if isinstance(sub, list) else sub for sub in inp]
print(out)
['and', ['or', 'P', '-R'], ['or', '-Q', '-R', 'P']]

要删除重复的子列表,请将列表转换为元组,再次使用fromkeys:

inp = ['and', ['or', 'P', '-R', 'P'], ['or', '-Q', '-R', 'P'], ['or', 'P', '-R', 'P']]
out = OrderedDict.fromkeys(tuple(OrderedDict.fromkeys(sub).keys()) if isinstance(sub, list) else sub for sub in inp)

print(out.keys())
['and', ('or', 'P', '-R'), ('or', '-Q', '-R', 'P')]

如果您想再次使用列表,只需在Python2中进行转换并使用iterkeys:
out = OrderedDict.fromkeys(tuple(OrderedDict.fromkeys(sub).iterkeys()) if isinstance(sub, list) else sub for sub in inp)
print([list(ele) if isinstance(ele, tuple) else ele for ele  in out.iterkeys()])

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