将列表分组为等效类

时间:2015-02-22 23:55:34

标签: python

假设我有一个事物列表和一个带有两个args的函数,并说如果它们是等价的,那么将它们分组到每个子列表是等价类的子列表列表中的最有效方法是什么。下面是我在输入这个问题时写的一些代码,但是有更好的方法吗?

def groupIntoEquivalencyClasses(aList, aEquals):
  tClasses = []
  for tElem in aList:
    tFound = False
    for tClass in tClasses:
      if aEquals(tClass[0], tElem):
        tFound = True
        tClass.append(tElem)
        break
    if not tFound:
      tClasses.append([tElem])
  return tClasses 

示例输入

tNums = []
for tNum in range(20):
  tNums.append(tNum)
tThreeDiv = lambda x,y: x % 3 == y % 3
print(groupIntoEquivalencyClasses(tNums, tThreeDiv))

示例输出

[[3, 6, 9, 12, 15, 18],[1, 4, 7, 10, 13, 16, 19], [2, 5, 8, 11, 14, 17]]

1 个答案:

答案 0 :(得分:2)

我认为你的方法很好。使用字典存储代表可能会更清晰:

def groupIntoEquivalencyClasses(aList, aEquals):
  classesByReps = {}
  for tElem in aList:
    tFound = False
    for rep in classesByReps.keys():
      if aEquals(tElem, rep):
        tFound = True
        classesByReps[rep].append(tElem)
        break
    if not tFound:
      classesByReps[tElem] = [tElem]  
      #or just classesByReps[tElem] = [] if you don't want to re-store the key/representative
  return tClasses 

如果你真的需要优化,那么你可以修改一个在比较时合并等价类的排序算法。