我正在尝试编写一个函数,以便在给定关系列表时返回true或false,无论它是否是反对称的。 如果(a,b)处于关系中且(b,a)处于关系中则a必须等于b
即。给[[“A”,“A”],[“A”,“C”],[“A”,“B”],[“C”,“C”]]将返回true
[[“A”,“A”],[“A”,“D”],[“D”,“A”]]将返回false,因为[A,D]和[D,A]在关系中但不相等
我的想法是:
def is_antisymmetric(relation):
for a, b in relation:
if (a,b) in relation and (b,a) in relation and a == b:
return True
else:
return False
但这似乎不起作用。任何帮助将不胜感激
答案 0 :(得分:0)
def is_antisymmetric(relation):
for a, b in relation:
if (a,b) in relation and (b,a) in relation and a != b:
return False
return True
print is_antisymmetric([("A","A"), ("A","C"), ("A","B"), ("C","C")]) # True
print is_antisymmetric([("A","A"), ("A","C"), ("C","A"), ("C","C")]) # False
或者如果您使用方括号
def is_antisymmetric(relation):
for a, b in relation:
if [a,b] in relation and [b,a] in relation and a != b:
return False
return True
print is_antisymmetric([["A","A"], ["A","C"], ["A","B"], ["C","C"]]) # True
print is_antisymmetric([["A","A"], ["A","C"], ["C","A"], ["C","C"]]) # False
答案 1 :(得分:0)
您的方法存在的一个问题是,in
list
的费用相对较高O(n)
,这使您当前的方法为O(n^2)
。一种简单而有效的O(n)
方法是将set()
in
中看到的每个项目添加为set()
O(1)
,例如:
def is_antisymmetric(relation):
seen = set()
for a, b in relation:
if a == b:
continue
if (b, a) in seen:
return False
seen.add((a, b))
return True
In []:
is_antisymmetric([["A","A"], ["A","C"], ["A","B"], ["C","C"]])
Out[]:
True
In []:
is_antisymmetric([["A","A"], ["A","D"], ["D","A"]])
Out[]:
False
一些时间......
import string
import itertools
rels = list(itertools.combinations(string.ascii_letters, 2))
目前的做法(由@Xin Huang确定):
In []:
%timeit is_antisymmetric_list(rels)
Out[]:
30.8 ms ± 727 µs per loop
使用上面的set()
方法:
In []:
%timeit is_antisymmetric_set(rels)
Out[]:
329 µs ± 2.99 µs per loop