あなたの問題は、配列内のすべての組み合わせのペアが一緒に推移的な関係if a>b and b>c then a>c
を持っているという離散数学の関係に関するものです。そのため、次のリストを作成できます。したがって、長さ 5 のセットでは、最小の要素はこれらのペアのうちの 4 つに含まれる必要があります。そのため、最初の要素でグループ化されたこれらのペアを最初に作成する必要があります。これにより、moduleから関数groupby
とchain
関数を使用できます。itertools
>>> 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
してください。次に、これらの要素の数を計算するために使用します。
>>> [(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)]
four or five
最初の部分で4,2,34 or 3
を見つけたので、次は 1 を見つけるだけfour
ですしたがって、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)]