您的问题完全与离散数学中的关系有关,即数组中的所有组合对都具有传递关系,这意味着if a>b and b>c then a>c。因此,您可以创建以下列表,因此在长度为 5 的集合中,最小元素应该在其中的 4 对中——如果我们有这样数量的对。所以首先我们需要创建这些按第一个元素分组的对,为此我们可以使用 itertools 模块中的 groupby 和 chain 函数:
>>> from itertools import combinations,chain,groupby
>>> from operator import itemgetter
>>> l1= [list(g) for _,g in groupby(sorted(chain.from_iterable(combinations(i,2) for i in [x,y,z])),key=itemgetter(0))]
[[('one', 'four'), ('one', 'four'), ('one', 'three'), ('one', 'two')], [('three', 'five'), ('three', 'four')], [('two', 'five'), ('two', 'four'), ('two', 'three')]]
因此,如果我们有 len 4 ,3 ,2, 1 的组,那么我们已经找到了答案,但是如果我们没有找到这样的序列,我们可以反向进行前面的计算以使用以下逻辑找到我们的元素,如果我们找到一个以 len 4 为最大数的关系组,然后...!
>>> l2= [list(g) for _,g in groupby(sorted(chain.from_iterable(combinations(i,2) for i in [x,y,z]),key=itemgetter(1)),key=itemgetter(1))]
[[('two', 'five'), ('three', 'five')], [('one', 'four'), ('two', 'four'), ('one', 'four'), ('three', 'four')], [('two', 'three'), ('one', 'three')], [('one', 'two')]]
所以我们可以做到以下几点:
注意我们需要使用set(zip(*i)[1])来获取我们的特定元素与其相关的元素集合,然后使用len来计算这些元素的数量。 p>
>>> [(i[0][0],len(set(zip(*i)[1]))) for i in l1]
[('one', 3), ('three', 2), ('two', 3)]
>>> [(i[0][1],len(set(zip(*i)[0]))) for i in l2]
[('five', 2), ('four', 3), ('three', 2), ('two', 1)]
在第一部分中,我们找到了 4,2,3,所以现在我们只需要找到可能是 four or five 的 1。现在我们进入第二部分,我们需要找到长度为 4 or 3 的序列four 为 3,因此已找到第 4 个元素,因此第 5 个元素应为 five。
编辑:作为一种更优雅、更快捷的方式,您可以使用collections.defaultdict 完成这项工作:
>>> from collections import defaultdict
>>> d=defaultdict(set)
>>> for i,j in chain.from_iterable(combinations(i,2) for i in [x,y,z]) :
... d[i].add(j)
...
>>> d
defaultdict(<type 'set'>, {'three': set(['four', 'five']), 'two': set(['four', 'five', 'three']), 'one': set(['four', 'two', 'three'])})
>>> l1=[(k,len(v)) for k,v in d.items()]
>>> l1
[('three', 2), ('two', 3), ('one', 3)]
>>> d=defaultdict(set)
>>> for i,j in chain.from_iterable(combinations(i,2) for i in [x,y,z]) :
... d[j].add(i) #create dict reversely
...
>>> l2=[(k,len(v)) for k,v in d.items()]
>>> l2
[('four', 3), ('five', 2), ('two', 1), ('three', 2)]