2016-09-06 30 views
2

“Big_file.txt”,我想提取“用户A”这是不符合在“Small_file.txt”的UID重复的UID的。我写了下面的代码,但它似乎永远不会停止运行。那么,如何加快这个过程呢?非常感谢你:)Python 3:如何比较两个大文件最快?

import json 

uid_available = [] 
linesB = [] 
for line in open('E:/Small_file.txt'): 
    line = json.loads(line) 
    linesB.append(hash(line['uid'])) 


for line in open('E:/Big_file.txt'): 
    line = json.loads(line) 
    if hash(line['uid']) not in linesB and line['user'] == 'User A': 
     uid_available.append(line['uid']) 

这是Big_file.txt的格式(有10个百万行):

{'uid': 111, 'user': 'User A'} 
{'uid': 222, 'user': 'User A'} 
{'uid': 333, 'user': 'User A'} 
{'uid': 444, 'user': 'User B'} 
{'uid': 555, 'user': 'User C'} 
{'uid': 666, 'user': 'User C'} 

这是Small_file.txt的格式(有几百万行):

{'uid': 333, 'user': 'User A'} 
{'uid': 444, 'user': 'User B'} 
{'uid': 555, 'user': 'User C'} 

输出我预计:

111 
222 
+0

使用一本字典,你会显著加快由执行查找'不in'。 – spectras

+1

您可以使用'set'而不是'list'来附加值来跳过检查是否有重复项。 –

+0

@spectras和vishes_shell非常感谢您的帮助:) – NGuyen

回答

3

查找列表中的项目需要O(n)时间。如果您使用dictset,则可以将其改进为O(1)

你可以做最短的修改是:

linesB = [] 
for line in open('E:/Small_file.txt'): 
    line = json.loads(line) 
    linesB.append(hash(line['uid'])) 
linesB = set(linesB) 

或做是正确的

​​
+2

查找'set'或'dict'中的项目的平均复杂度为_O(1)_。看看[这个页面](https://wiki.python.org/moin/TimeComplexity)。所以你的解决方案甚至比你想象的要好:) – spectras

+0

感谢您的评论。我来自C++背景,经常犯这个错误。 – Tempux

+0

你当然可以在C++中拥有相同的功能,事实上CPython解释器是用C语言编写的。他们为'dict'选择了一个不同的实现,使用了一个哈希表[一些调整](http://svn.python.org/项目/蟒/中继/对象/ dictobject.c)。它的主要优点是查找速度非常快,但它显然必须在其他操作中支付,最显着的是插入时最糟糕的情况。 – spectras