我认为这行得通...
a = [[283, 311], [311, 283, 316], [150, 68], [86, 119], [259, 263], [263, 259, 267], [118, 87], [262, 264], [264, 262], [85, 115], [115, 85], [244, 89], [140, 76, 82, 99], [236, 111], [330, 168], [76, 63, 107, 124, 128, 135, 140], [131, 254], [254, 131], [21, 38], [38, 21], [220, 291], [291, 220], [296, 46], [64, 53, 57, 61, 63, 65, 66, 76, 96, 100, 103, 114, 123, 127, 128, 130, 148, 149], [274, 240], [157, 225, 234], [225, 247], [233, 44], [89, 244], [80, 101], [210, 214], [78, 155], [55, 139], [102, 74, 75, 132], [105, 252], [149, 55, 59, 63, 71, 73, 81, 100, 102, 116, 122, 138, 146], [97, 231], [231, 97], [155, 78], [239, 305], [305, 239], [145, 94, 248], [147, 150], [61, 64], [152, 219], [219, 152], [246, 250], [252, 105], [223, 235], [235, 223], [237, 60, 344], [344, 237], [182, 129], [331, 117], [12, 2, 8, 10, 13, 15], [250, 246]]
aa = set(map(frozenset,a)) #eliminate duplicates
result = [x for x in aa if not any(x < y for y in aa)]
请注意,这会为您提供frozenset
对象列表,但您可以轻松地将其转换回列表列表:
result = [list(fset) for fset in result]
不幸的是,它具有二次复杂性......我不确定是否真的有什么要做的......(将其保留为列表会导致更糟糕的复杂性 FWIW)
这是第二种方法,在算法上要好一些:
from itertools import takewhile
def foo2(aa):
aa = sorted(set(map(frozenset,a)),key=len)
def conditional(x,aa):
xlen = len(x)
return any(x < y for y in takewhile(lambda z: xlen <= len(z),aa))
return [x for x in aa if not conditional(x,aa)]
当然,它需要对你的真实数据进行计时,看看它是否真的表现得更好(对于测试数据,列表不够大,生成conditional
函数和takewhile
实例的开销lambda
使得它不值得。
出于好奇,这是我的基准:
a = [[283, 311], [311, 283, 316], [150, 68], [86, 119], [259, 263], [263, 259, 267], [118, 87], [262, 264], [264, 262], [85, 115], [115, 85], [244, 89], [140, 76, 82, 99], [236, 111], [330, 168], [76, 63, 107, 124, 128, 135, 140], [131, 254], [254, 131], [21, 38], [38, 21], [220, 291], [291, 220], [296, 46], [64, 53, 57, 61, 63, 65, 66, 76, 96, 100, 103, 114, 123, 127, 128, 130, 148, 149], [274, 240], [157, 225, 234], [225, 247], [233, 44], [89, 244], [80, 101], [210, 214], [78, 155], [55, 139], [102, 74, 75, 132], [105, 252], [149, 55, 59, 63, 71, 73, 81, 100, 102, 116, 122, 138, 146], [97, 231], [231, 97], [155, 78], [239, 305], [305, 239], [145, 94, 248], [147, 150], [61, 64], [152, 219], [219, 152], [246, 250], [252, 105], [223, 235], [235, 223], [237, 60, 344], [344, 237], [182, 129], [331, 117], [12, 2, 8, 10, 13, 15], [250, 246]]
def foo1(aa):
aa = set(map(frozenset,a)) #eliminate duplicates
return [x for x in aa if not any(x < y for y in aa)]
from itertools import takewhile
def conditional(x,aa,takewhile=takewhile):
xlen = len(x)
return any(x < y for y in takewhile(lambda z: xlen <= len(z),aa))
def foo2(aa):
aa = sorted(set(map(frozenset,a)),key=len)
return [x for x in aa if not conditional(x,aa)]
print set(foo1(a)) == set(foo2(a))
import timeit
N = 10000
print timeit.timeit('foo1(a)','from __main__ import foo1,a',number=N)
print timeit.timeit('foo2(a)','from __main__ import foo2,a',number=N)