在python上优化列表中列表的迭代

时间:2018-01-30 04:32:51

标签: python optimization

我有一些优化问题(我是python和Stackoverflow的新手)。

我正在为一个研究项目建立一个单词搭配网络。我编写的代码采用了一个没有停用词(text_c)的词干文本,并将其拆分为句子。对于每个句子,它会迭代这些术语,以构建一个称重的语义网络,然后我将使用NetworkX进行处理。这部分是基于{'word':digit}形式的字典(下面的dic)。代码迭代网络中现有边缘的列表(表示为3个项目的列表)。

问题可能是网络上的循环如何呈指数级增长(每次添加新的边/列表时,循环的大小都会增加)。文中有大约110K的句子,所以这花费了太多时间(最后花了4个小时才完成,但没有完成)。必须有更好的方法来做到这一点。 “for”声明会比看起来更有效吗?这将如何运作?

谢谢!

#determine semantic networks    
outfile = open("00_network_"+str(c)+".csv","a")
network = []
er=0
data = text_c.split(".")
for lines in data:
    linew = lines.split()
    ran = len(linew)
    if ran>3: #sentences of more than three words
        i=0
        while i < ran:
            j = i+1
            while j < ran:
                try:
                    previous_edge = []
                    for n in network:
                        if n[0] == dic[linew[i]] and n[1] == dic[linew[j]]:
                            previous_edge = [n[0],n[1],n[2]]

                    if previous_edge == []:
                        new_edge = [dic[linew[i]],dic[linew[j]],1/((j-i))]
                        network.append(new_edge)
                    else:
                        new_edge = [dic[linew[i]],dic[linew[j]],previous_edge[2]+1/((j-i))]
                        network.remove([previous_edge[0],previous_edge[1],previous_edge[2]])
                        network.append(new_edge)
                except KeyError:
                    er=er+1

                j=j+1
            i=i+1

1 个答案:

答案 0 :(得分:0)

ij未在循环内被操纵。

  • 使用forrange

dic[linew[i]]dic[linex[j]]在循环内进行比较,每次都会获取值。

  • 将值缓存在循环之外

当您找到break时,您可能需要previous_edge,从而避免(多次)不需要的迭代

不要测试空列表的相等性。 not thislist足以知道列表是否有内容。

不要使用其3个值重新创建previous_edge以将其从网络中删除

# determine semantic networks
outfile = open("00_network_" + str(c) + ".csv", "a")
network = []
er = 0
data = text_c.split(".")
for lines in data:
    linew = lines.split()
    ran = len(linew)
    if ran > 3:  # sentences of more than three words
        # use for and ranges
        for i in range(ran):
            dli = dic[linew[i]]
            for j in range(ran):
                try:
                    previous_edge = []
                    # cache dictionary access before going into for n loop
                    dlj = dic[linew[j]]
                    for n in network:
                        if n[0] == dli and n[1] == dlj:
                            previous_edge = [n[0], n[1], n[2]]
                            # DON'T YOU WANT A BREAK HERE?
                            break

                    if not previous_edge:  # negative test is enough
                        new_edge = [dli, dlj, 1/(j-i)]
                        network.append(new_edge)
                    else:
                        new_edge = [dli, dlj, previous_edge[2] + 1/(j-i)]
                        # DON'T RECREATE a LIST to remove the edge
                        network.remove(previous_edge)
                        network.append(new_edge)
                except KeyError:
                    er = er + 1