基于Python的脚本,用于从文件中删除另一个文件中显示的行



我有一个文件all_projects.txt,其中包含:

java/my_project_wwe
java/my_project_wwf
java/my_project_wcw
net/my_project_aew
net/my_project_impact
net/my_project_njpw

我有另一个文件project_to_delete.txt,其中包含:

java/my_project_wcw
net/my_project_njpw

因此,我想接收:

java/my_project_wwe
java/my_project_wwf
net/my_project_aew
net/my_project_impact

它通过bash:
grep -v -x -f project_to_delete.txt all_projects.txt
运行得很好,但我想通过python来实现。当然,我们可以做一些类似模块os.systemsubprocess的事情,但我正在寻找的不是。我试着这样做:

with open('all_projects.txt','r') as read1:
f1 = read1.readlines()
with open('project_to_delete.txt', 'r') as read2:
f2 = read2.readlines()
with open('result.txt', 'w+') as write1:
for line in f1:
if line in f2:
write1.write(line + 'n')

但在result.txt中,我有:

java/my_project_wcw
net/my_project_njpw

哪里有错误
感谢您的关注,也感谢您的帮助。

您的if条件不正确。您正在查找f1和f2中相同的直线。如果线路不在f2中,则您的if条件应为

with open('result.txt', 'w+') as write1:
for line in f1:
if line not in f2:  #Nottice the not here
write1.write(line + 'n')

@Saad_Khan的答案是正确的,但我只是想就你的问题提出一点,每当我读到这样的问题时,我都会强调这一点,这是关于数据抽象的一点。

你写问题的方式是关于";删除文件中的行";其与";"另一个文件中的行";。但是你的问题真的很大程度上取决于文件吗?在这种情况下,可能有一点,因为您提到了对grep执行同样的操作,并且像grep这样的命令行实用程序倾向于面向文件/流。

但在像Python这样的编程语言中,你可能会尽量少考虑";文件";以及关于在这些文件中序列化的数据结构的更多信息。在这种情况下,只是字符串列表。

所以你的问题变成了,如何计算两个字符串列表的差?因为你最初写问题的方式只是使用readlines()将文件的全部内容读取到列表中(如果你在大文件上迭代,问题可能会有点不同,但不会太大(。

那么,你如何看待两个列表之间的区别呢?

一个简单的方法是使用set.difference:

>>> list_a = [1, 2, 3, 4, 5]
>>> list_b = [3, 5, 6]
>>> set_c = set(list_a).difference(list_b)
>>> set_c
set([1, 2, 4])

由于set不能保证是有序的,如果您希望输出是可预测的,您可以对输出进行排序:

>>> list_c = sorted(set_c)

然而,一个更常见的模式更像@sad_Khan的答案,保留了列表a的原始顺序;你可以通过列表理解来做到这一点,比如:

>>> list_c = [s for s in list_a if s not in list_b]

然而,这可能有点慢,因为如果list_b很大,则它必须在每个循环中对最多list_b的每个元素(在最坏的情况下(执行字符串比较。因此,更常见的模式是将list_b转换为set:

>>> set_b = set(list_b)
>>> list_c = [s for s in list_a if s not in set_b]

这样做的优点是,每个if s not in set_b都具有O(1(行为,而if s not in list_blist_b的大小上具有O(n(行为。

既然您的工具带中有了这些更通用的技术,那么担心如何处理结果与读取/写入文件是一个完全独立的问题。

给定list_c,您现在可以以任何方式将其写入第三个文件。或者,如果您想编写像grep这样的命令行实用程序,有时只调用print()并允许用户使用shell重定向(如果他们想将结果输出到文件中(是很有用的:

>>> print('n'.join(list_c))

最新更新