1

我有一组来自两个不同目录的文件名。

currList=set(['pathA/file1', 'pathA/file2', 'pathB/file3', etc.])

我的代码正在处理文件,并且需要通过将其与前一次迭代中的内容进行比较来更改 currList,例如 processLst。为此,我计算了一个对称差异:

toProcess=set(currList).symmetric_difference(set(processList))

实际上,我需要 symmetric_difference 对基本名称(file1...)而不是对完整文件名(pathA/file1)进行操作。

我想我需要重新实现__eq__运算符,但我不知道如何在 python 中做到这一点。

  1. 重新__eq__实施正确的方法吗?或者
  2. 还有另一种更好/等效的方法吗?
4

2 回答 2

2

这是一个令牌(并且可能构造不佳)itertools版本,如果速度成为一个问题,它应该运行得更快一些(尽管同意@Zarkonnen 的单线非常甜蜜,所以+1 :))。

from itertools import ifilter

currList = set(['pathA/file1', 'pathA/file2', 'pathB/file3'])
processList=set(['pathA/file1', 'pathA/file9', 'pathA/file3'])

# This can also be a lambda inside the map functions - the speed stays the same
def FileName(f):
  return f.split('/')[-1]

# diff will be a set of filenames with no path that will be checked during
# the ifilter process
curr = map(FileName, list(currList))
process = map(FileName, list(processList))
diff = set(curr).symmetric_difference(set(process))

# This filters out any elements from the symmetric difference of the two sets
# where the filename is not in the diff set
results = set(ifilter(lambda x: x.split('/')[-1] in diff,
              currList.symmetric_difference(processList)))
于 2012-10-09T15:24:48.943 回答
1

您可以使用生成器表达式的魔力来做到这一点。

def basename(x):
    return x.split("/")[-1]

result = set(x for x in set(currList).union(set(processList)) if (basename(x) in [basename(y) for y in currList]) != (basename(x) in [basename(y) for y in processList]))

应该做的伎俩。它为您提供了出现在一个列表或另一个列表中的所有元素 X,并且它们在两个列表中的基本名称存在不相同。

编辑: 运行这个:

currList=set(['pathA/file1', 'pathA/file2', 'pathB/file3'])
processList=set(['pathA/file1', 'pathA/file9', 'pathA/file3'])

返回:

set(['pathA/file2', 'pathA/file9'])

这似乎是正确的。

于 2012-10-09T08:53:57.793 回答