【问题标题】:Python For Loop Slows Due To Large List由于列表大,Python For 循环变慢
【发布时间】:2019-06-22 21:56:23
【问题描述】:

所以目前我有一个 for 循环,这会导致 python 程序因程序说“已杀死”而死。它减慢了大约 6000 个项目,该程序在大约 6852 个列表项目中缓慢死亡。我该如何解决这个问题?

我认为这是由于列表太大。

我尝试将列表分成两部分,大约为 6000。可能是由于内存管理或其他原因。帮助将不胜感激。

    for id in listofids:
        connection = psycopg2.connect(user = "username", password = "password", host = "localhost", port = "5432", database = "darkwebscraper")

        cursor = connection.cursor()
        cursor.execute("select darkweb.site_id, darkweb.site_title, darkweb.sitetext from darkweb where darkweb.online='true' AND darkweb.site_id = %s", ([id]))
        print(len(listoftexts))

        try:
            row = cursor.fetchone()
        except:
            print("failed to fetch one")
        try:
            listoftexts.append(row[2])
            cursor.close()
            connection.close()
        except:
            print("failed to print")

【问题讨论】:

  • 您确定每次循环都需要关闭并重新打开连接吗?
  • khelwood,我这样做是为了检查它是不是光标对象变得超载,在此之前存在同样的问题。
  • 尝试将数据库连接移出循环并在上下文管理器中使用它。
  • 我很确定数据库连接不是问题

标签: python-3.x list for-loop psycopg2


【解决方案1】:

你是对的,这可能是因为列表变大了:python 列表是内存中的连续空间。每次追加到列表时,python 都会查看下一个位置是否有一个点,如果没有,他会将整个数组重新定位到有足够空间的地方。你的数组越大,要重定位的 python 就越多。

一种解决方法是预先创建一个大小合适的数组。

编辑:为了确保清楚,我举了一个例子来说明我的观点。我做了2个功能。第一个在每次迭代时将字符串化索引(使其更大)附加到一个列表中,另一个只是填充一个 numpy 数组:

import numpy as np
import matplotlib.pyplot as plt
from time import time

def test_bigList(N):
    L = []
    times = np.zeros(N,dtype=np.float32)

    for i in range(N):
        t0 = time()
        L.append(str(i))
        times[i] = time()-t0

    return times

def test_bigList_numpy(N):
    L = np.empty(N,dtype="<U32")
    times = np.zeros(N,dtype=np.float32)

    for i in range(N):
        t0 = time()
        L[i] = str(i)
        times[i] = time()-t0
    return times

N = int(1e7)
res1 = test_bigList(N)
res2 = test_bigList_numpy(N)

plt.plot(res1,label="list")
plt.plot(res2,label="numpy array")
plt.xlabel("Iteration")
plt.ylabel("Running time")
plt.legend()
plt.title("Evolution of iteration time with the size of an array")
plt.show()

我得到以下结果:

您可以在图中看到,对于列表的情况,您经常会出现一些峰值(可能是由于重新定位),并且它们似乎随着列表的大小而增加。这个例子是用短的附加字符串,但字符串越大,你会看到越多的效果。

如果它不能解决问题,那么它可能与数据库本身相关联,但如果不了解数据库的具体情况,我无法帮助您。

【讨论】:

  • 好的,那么我该如何设置一个大小为 '11533' 的数组,将文本项添加到其中,然后将其转换为列表?
  • 它肯定会与 numpy 数组一起使用(因为您事先使用“
  • 我已经预先创建了一个列表,但问题仍然存在。我不确定你的建议是否有效。
  • 我做了一个例子,只是为了确保我清楚。但如果这不起作用,那么我不确定它会是什么
  • 你可能是对的。然而,我用另一种方法解决了这个问题,即把我正在运行实验的机器换成内存更大的机器。
猜你喜欢
  • 2011-10-31
  • 2016-02-05
  • 1970-01-01
  • 2018-10-15
  • 1970-01-01
  • 1970-01-01
  • 2015-01-28
  • 2017-06-04
  • 1970-01-01
相关资源
最近更新 更多