我目前正在处理python中的一个无向图,其中边用元组表示(A和B之间的边由(A,B)或(B,A)表示)。我想知道是否有一个元组操作可以对元组执行这样的无定向比较:
exp1 = undirected_comp((A,B), (B,A)) #exp1 should evaluate to True
exp2 = undirected_comp((A,B), (A,C)) #exp2 should evaluate to False发布于 2014-01-09 19:47:31
不完全是这样,但总的来说,您可以做这种比较
set (A,B) == set (B, A)发布于 2014-01-09 19:52:21
当然:undirected_comp = lambda e1,e2: e1==e2 or (e1[1],e1[0])==e2
因为边总是精确的2元组,它应该是足够健壮的,假设A和B对象定义相等。
编辑(无耻的自我提升):您可能不希望为每个比较器创建两个set对象的开销,特别是如果这是一个更大的算法的一部分。集合很适合查找,但是实例化要慢得多:https://stackoverflow.com/a/7717668/837451
发布于 2014-01-09 19:53:18
除了使用sets的解决方案之外,还可以轻松地使用您自己的比较函数:
In [1]: def undirected_comp(tup1, tup2):
...: return tup1 == tup2 or tup1 == tup2[::-1]
In [2]: undirected_comp(('A','B'), ('B','A'))
Out[2]: True
In [3]: undirected_comp(('A','B'), ('A','C'))
Out[3]: False
In [4]: undirected_comp(('A','B'), ('A','B'))
Out[4]: True正如mmdanziger所指出的,这比使用集合的解决方案要快,因为您不必支付设置创建的成本。
但是,如果您关心速度和,那么您花更多的时间比较不同的边缘,而不是创建它们,最好不要将边缘存储为具有任意顺序的元组,而是对它们进行预处理,并以不同的格式存储它们。最好的两个选项可能是frozenset或排序元组(即按照约定,总是先存储最小的节点)。一些快速的时机:
# edge creation, this time is spent only once, so presumably we don't care:
In [1]: tup1 = (1, 2); tup2 = (2, 1)
In [2]: fs1 = frozenset(tup1); fs2 = frozenset(tup2)
In [3]: sorted_tup1 = tuple(sorted(tup1)); sorted_tup2 = tuple(sorted(tup2))
# now time the comparison operations
In [4]: timeit set(tup1) == set(tup2) # Corley's solution
1000000 loops, best of 3: 674 ns per loop
In [5]: timeit tup1 == tup2 or tup1 == tup2[::-1] # my solution above
1000000 loops, best of 3: 348 ns per loop
In [6]: timeit fs1 == fs2 # frozensets
10000000 loops, best of 3: 120 ns per loop
In [7]: timeit sorted_tup1 == sorted_tup2 # pre-sorted tuples
10000000 loops, best of 3: 83.4 ns per loop因此,假设您不关心边缘的创建时间,那么将其存储为排序元组是进行比较的最快方法。在这种情况下,您只需要做一个简单的比较,而不需要比较向后的情况,因为顺序是由预排序保证的。
https://stackoverflow.com/questions/21029678
复制相似问题