0

我正在创建从一个相当大的 txt 文件派生的对象。我的代码工作正常,但需要很长时间才能运行。这是因为我首先要寻找的元素不是有序的,也不是(必然)唯一的。例如,我正在寻找一个可能在文件中使用两次但可能位于第一行和最后一行的数字代码。我的想法是检查某个代码的使用频率...

counter=collections.Counter([l[3] for l in self.body])

...然后循环通过计数器。高级:如果仅在不必遍历整个文件时才使用代码。但是,您遇到了很多迭代,这使得该过程非常缓慢。

所以我的问题真的是:我怎样才能改进我的代码?当然,另一个想法是先对数据进行排序。但这也可能需要很长时间。

关键部分是这个方法:

def get_pc(self):
    counter=collections.Counter([l[3] for l in self.body])
    # This returns something like this {'187':'2', '199':'1',...}

    pcode = []

    #loop through entries of counter
    for k,v in counter.iteritems():
        i = 0
        #find post code in body
        for l in self.body:
            if i == v:
                break
            # find fist appearence of key 
            if l[3] == k:
                #first encounter...
                if i == 0:
                    #...so create object
                    self.pc = CodeCana(k,l[2])
                    pcode.append(self.pc)
                i += 1
                # make attributes
                self.pc.attr((l[0],l[1]),l[4])
            if v <= 1:
                break
    return pcode

我希望代码能充分解释问题。如果没有,请告诉我,我将扩展提供的信息。

4

1 回答 1

2

你循环了body太多次。将其折叠成一个循环,并改为跟踪CodeCana字典中的项目:

def get_pc(self):
    pcs = dict()    
    pcode = []

    for l in self.body:
        pc = pcs.get(l[3])
        if pc is None:
            pc = pcs[l[3]] = CodeCana(l[3], l[2])
            pcode.append(pc)
         pc.attr((l[0],l[1]),l[4])

    return pcode

首先计算所有项目,然后尝试限制循环body多次,同时仍然循环遍历所有不同类型的项目,这在某种程度上违背了目的......

您可能需要考虑在l名称中给出各种索引。您可以使用元组解包:

for foo, bar, baz, egg, ham in self.body:
    pc = pcs.get(egg)
    if pc is None:
        pc = pcs[egg] = CodeCana(egg, baz)
        pcode.append(pc)
     pc.attr((foo, bar), ham)

但是构建基于body-的类将有助于代码文档和调试更多。namedtuple

于 2013-07-12T12:31:41.267 回答