我正在创建从相当大的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
我希望代码充分解释问题。如果没有,请告诉我,我将扩展提供的信息。
答案 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
将有助于代码文档和调试。