Python:如何更好地编写以下代码?

时间:2012-07-04 02:57:47

标签: python optimization

我对python很新,因此并不完全了解它的强大功能。我有以下代码,我认为应该更快。我有一个感觉,它可以使用numpy / map完成,但不知道如何构建它。

这里所讨论的词典都有10,000个键,其值由7个元素列表组成,如:

T_com ={0: [[1.2, 3,.65,.63, 3, 3 , 5.5]] 1:[[1.7, 2,.55,.13, 2, 8 , 5.5]] ...10,000th key:[[3.2, 9,.15,.23, 1, 3 , 2.5]]}

为此,我目前的代码(下面讨论过)延伸到小时,我感觉并不好。基本上,我正在读取与两个词典中的每个键相关联的列表,计算它们上的分数,然后将分数附加到字典并最终将其写入ZODB。以下是摘录(字典R_com在结构上与上面定义的T_com完全相似。):

 for tar_node,tar_community in T_com.iteritems():   # iterate over the key value pair of first dic
     for i,(ref_node,ref_community) in enumerate(R_com.iteritems()):  # iterate over second dictionary. Enumeration was required for some other operation
         score = compute_score(T_com[tar_node],R_com[ref_node])      # calculate some score   
         bTree_container.setdefault(tar_node,PersistentList () ).append( [ref_node,score,priority.pop(),0])    #Builds a list of lists associated with every value of tar_node
         if i % 2500 ==0:            # After every 2,500 values temporarily save the data to disk
             transaction.savepoint(True)
 transaction.commit()  # finally write all the data to disk 

有关如何减少运行时间/避免循环的任何建议?在genreal中,python中处理这种情况的最佳实践是什么?

正如所建议的,cProfile的一些结果: -

200000000 3792.449    0.000 3792.449    0.000 {numpy.core.multiarray.array}
100000000   51.033    0.000   51.186    0.000 {method 'setdefault' of 'BTrees.IOBTree.IOBTree' objects}

3 个答案:

答案 0 :(得分:0)

从它的外观来看,您正在为每个迭代的字典中的每个元素创建一个树和一个新节点。

如果您需要检查字典的每个元素以计算得分,那么您唯一的另一个选择就是拥有一个包含一些计算的辅助资源,这将阻止您不得不重复每个字段。

同样,您可以保留每个字典生成的树的副本,然后在获取更多信息时将其添加到每个字典中,并最终将它们全部链接在一起。

很抱歉,我会将此作为评论,但我不允许发表评论,也可能无法弄明白......

无论如何,祝你好运!

答案 1 :(得分:0)

score = compute_score(T_com[tar_node]tar_community,R_com[ref_node]ref_community)

这可以节省一些dict查找时间,但你的根问题是x * y;如果你真的需要这个,并且非常关心运行时间,可以考虑使用cython或纯c代码来加速

答案 2 :(得分:0)

即使每次执行compute_score只需要1ms,如果你在T_com中有10k个元素而在R_com中有10k个元素,这将需要10k * 10k * 1ms,这大约是27小时。你提出的方式,这是一个O(n2)问题。你能简化你的逻辑吗?如果不能,则需要其他技术 - 例如并行或分布式执行。

==编辑==

正如您在评论中所解释的,这是一个点积。你能尝试将它减少到O(n)吗?类似的东西:

scores = []
for index in T_com.keys():
    score = T_com[index] * R_com[index]
dot_product = sum(scores)