【问题标题】:Python: How to speed up creating of objects?Python:如何加快对象的创建速度?
【发布时间】:2013-07-12 20:37:01
【问题描述】:

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

我希望代码能够充分说明问题。如果没有,请告诉我,我会扩展提供的信息。

【问题讨论】:

  • 对于初学者:使用生成器表达式而不是列表推导。您不需要中间人列表。 Counter(l[3] for l in self.body) 就够了。
  • 为什么在循环中设置self.pc?它很快就会被下一个CodeCana 对象取代。为什么本地人不来这里?
  • 数据是什么样的?
  • 文件中有一些基本信息。所以单个对象应该有一次代码和名称,但其他数据应该添加到列表中。我希望返回对象列表,这样我就可以做类似pco = mp.get_pc()pco[0].nodes

标签: python optimization python-2.7 iteration


【解决方案1】:

您在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 将有助于代码文档和调试更多。

【讨论】:

  • 确实如此。有点卡住了。感谢您的思考。
  • 感谢您的有用建议。
猜你喜欢
  • 2015-09-11
  • 2016-05-20
  • 2020-08-20
  • 1970-01-01
  • 2016-02-23
  • 1970-01-01
  • 2011-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多