确定列表是否是反对称的

时间:2018-04-19 01:43:50

标签: python list relation

我正在尝试编写一个函数,以便在给定关系列表时返回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

但这似乎不起作用。任何帮助将不胜感激

2 个答案:

答案 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