Python:如何加速对象的创建?

时间:2013-07-12 12:23:51

标签: python optimization python-2.7 iteration

我正在创建从相当大的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

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

1 个答案:

答案 0 :(得分: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)

但是从a namedtuple-based class构建body将有助于代码文档和调试。