我正在阅读 Steven 和 Dusty 的 Python 面向对象编程。
我在第 10 章,都是关于迭代器设计模式的。本章末尾有一个练习,编写生成器函数/表达式以查找两个文件之间的公共行。
这是我天真的方法:
old = os.path.normpath('E:/testing/old.txt')
new = os.path.normpath('E:/testing/new.txt')
res = []
def func(source):
for line in source.readlines():
yield line
方法一:
with open(old, "r") as f:
for line in func(f):
with open(new, "r") as _f:
for _line in func(_f):
if line == _line:
res.append(line)
方法二:
with open(old, "r") as f:
for line in func(f):
with open(new, "r") as _f:
res.extend(filter(lambda a: line == a, func(_f)))
上下文:
现在,让我们考虑完全不同的问题,假设我们有字符串列表而不是带有
n
和 m
元素的文件,我们可以在 O(n)
时间复杂度和 O(m)
空间中找到常见字符串。
我的最终目标是在时间和空间复杂度方面优化我的代码(如果可能的话),并使其更像 pythonic。
附言- 谁能给我指点 linux
diff
命令和 git-diff
源代码的源代码。
我试图找到 linux
diff
和 git-diff
的源代码,但找不到。
我不认为使用生成器可以最好地解决这个问题。我的方法是:
old = 'E:/testing/old.txt'
new = 'E:/testing/new.txt'
with open(old) as f:
old_lines = set(f) # A set of lines
with open(new) as f:
matches = [line for line in f if line in old_lines]
print(matches)
如果你想比较去掉尾随换行符的行(因为最后一行可能没有尾随换行符),那么你可以使用下面的代码,它也演示了创建两个集合并对它们进行“交集”操作。这样您就不必显式地循环遍历行。但是,您无法控制打印匹配项的顺序:
old = 'E:/testing/old.txt'
new = 'E:/testing/new.txt'
with open(old) as f:
old_lines = set(line.strip('\n') for line in f) # A set of lines
matches = []
with open(new) as f:
matches = set(line.strip('\n') for line in f) and old_lines
print(matches)
如果我是你,我会使用
set
,他们可以在(几乎)恒定的时间内进行会员测试。 some_set.intersection(some_other_set)
产生他们的共同成员。它真的很快因为他们使用哈希表.