检查代码的有效性



我有两个文件

此形式的tree_0:

443457316403167232  823615  Tue Mar 11 18:43:57 +0000 2014  2   
452918771813203968  26558552    Tue Mar 11 21:10:17 +0000 2014  0   
443344824096538625  375391930   Tue Mar 11 11:16:57 +0000 2014  9   
452924891285581824  478500516   Tue Mar 11 11:38:14 +0000 2014  0   

树.json

{"reply": 0, "id": 452918771813203968, "children": [{"reply": 0, "id": 452924891285581824, "children": []}]}

现在,我必须通过文件 trees.json 并在 tree_0 中找到 id,如果它存在,那么我必须执行一些任务。

我已经使用 readlines() 加载了tree_0。这两个文件都非常大(大小为10GB)。我已经编写了一段代码,但想知道这段代码是否可以,或者可以有更高效的代码。至于每个 ID,这都潜入整个tree_0(while 循环)。

import json
import sys
sys.setrecursionlimit(2000)
fr=open('tree_0','r')
lines=fr.readlines()
l=len(lines)
# to find children of trees, this works fine
def get_children(node):
    stack = [node]
    while stack:
        node = stack.pop()
        stack.extend(node['children'][::-1])
        yield node 
f = open('trees.json','r') 
linenum=0       
for line in f:
     d = json.loads(line)
     child_dic={}
     if (linenum<1000):
         for child in get_children(d):
             if child not in child_dic.keys():
                 i=0
                 while (i< l): # checkwhetherthis makes it slow as my files are large
                     data=lines[i].split('t')
                     # search for id in the tree_0 file
                     if str(child["id"])==str(data[0]): 
                         print "Perform some task here"
                     i=i+1

我认为你在这里做了很多不必要和低效的工作。首先,由于您只需要 ID,因此不必将整个tree_0文件存储在内存中。与其每次都遍历所有行并提取 ID,不如在加载文件时只执行一次。此外,您可以将 ID 存储在 set 中。这将大大提高查找速度。

with open('tree_0') as f:
    all_ids = set(int(line.split('t')[0]) for line in f)

如果您确实也需要tree_0中的其他字段,则可以将其设置为字典,将 ID 映射到其他字段。这仍然比每次循环列表具有更快的查找速度。

with open('tree_0') as f:
    all_ids = dict((int(items[0]), items) for items in (line.split('t') for line in f))

通过此更改,代码的其余部分归结为:

with open('trees.json') as f: 
    for line in f:
        d = json.loads(line)
        for child in get_children(d):
            if child["id"] in all_ids:
                # optional: get other stuff from dict
                # other_stuff = all_ids[child["id"]]
                print "Perform some task here"

更新:如果tree_0中的"ID"不是唯一的,即如果您有多行具有相同的 ID,您可以使用例如 A defaultdict将 ID 映射到其他属性的列表,如下所示

with open('tree_0') as f:
    all_ids = collections.defaultdict(list)
    for line in f:
        items = line.split('t')
        all_ids[int(items[0])].append(items)

然后,在代码的另一部分,只需对列表中的所有条目执行任务:

            if child["id"] in all_ids:
                for other_stuff in all_ids[child["id"]]:
                    print "Perform some task here", other_stuff

最新更新