我将一些代码从C ++移植到Python,它依赖于使用自定义比较函数的地图中键的C ++排序。我假设我可以简单地使用Python字典,然后在键上使用sorted(),使用等效函数作为键=到sorted()。但是,无论我如何尝试,都会在Python中以不同的顺序遍历键。
C ++代码是我在gitub上找到的gSpan的一些随机实现here。请参阅src / gspan.h和src / graph.h中的ProjectionMap和struct dfs_code_t。
我的简化python代码如下,包括C ++代码中两个比较函数的直接副本:
dfs_code = collections.namedtuple('dfs_code',
['fromn','to','from_label','edge_label','to_label'])
def dfs_code_compare(a, b):
if a.from_label != b.from_label:
return a.from_label < b.from_label
else:
if a.edge_label != b.edge_label:
return a.edge_label < b.edge_label
else:
return a.to_label < b.to_label
def dfs_code_backward_compare(a, b):
if a.to != b.to:
return a.to < b.to
else:
return a.edge_label < b.edge_label
# code that fills in a dictionary called pm
for pm in sorted(projection_map, key=functools.cmp_to_key(dfs_code_compare)):
print pm
上面的python代码产生以下顺序:
dfs_code(fromn=0, to=1, from_label=1, edge_label=0, to_label=3)
dfs_code(fromn=0, to=1, from_label=2, edge_label=3, to_label=2)
dfs_code(fromn=0, to=1, from_label=1, edge_label=3, to_label=3)
dfs_code(fromn=0, to=1, from_label=1, edge_label=1, to_label=2)
dfs_code(fromn=0, to=1, from_label=2, edge_label=1, to_label=3)
....
哪个是a)与C ++代码不同,b)根本不是我对比较函数所期望的(我希望所有from_labels为1在前面组合在一起,例如)。有任何想法吗?它与functools.cmp_to_key有关吗?
答案 0 :(得分:4)
在python中,比较函数必须返回负值,正值或零值,指示第一个元素是小于,大于还是等于第二个元素。因为python的&lt;运算符返回一个bool,你的问题来自python将False转换为0并假设这些值相等。
您可以重写比较函数以使用此约定,但可能更容易编写关键函数。
例如,dfs_code_compare可以转换为此键功能:
def dfs_code_key(pm):
return (pm.from_label, pm.edge_label, pm.to_label)
并像这样使用:
for pm in sorted(projection_map, key=dfs_code_key):
pm