【问题标题】:Speed up the List appending process加快列表追加过程
【发布时间】:2021-09-21 23:10:02
【问题描述】:

我想加快下面代码的进程

x = []
y = []
z = []
for i in range(0, 1000000):
    if 0 < u[i] < 1920 and 0 < v[i] < 1080:
        x.append(u[i])
        y.append(v[i])
        z.append([x_ind[i], y_ind[i]])

任何想法都将不胜感激。 谢谢

【问题讨论】:

  • 我们可以像 u = [1, 1920] * (n // 2) 一样定义 u

标签: python list for-loop


【解决方案1】:

通常,您可以通过替换索引上的循环并用原始值上的循环进行索引来优化这种情况。所以这里的替换代码是:

x = []
y = []
z = []
for a, b, c in zip(u, v, ind):
    if 0 < a < 1920 and 0 < b < 1080:
        x.append(a)
        y.append(b)
        z.append([c, c])

如果uvind 可能比1000000 长并且您必须1000000 处停止检查项目,您只需在顶部添加一个导入文件from itertools import islice,并将for循环本身更改为:

for a, b, c in islice(zip(u, v, ind), 1000000):

无论哪种方式,您都会从代码中删除所有索引(索引具有开销与在 CPython 参考解释器中完成的有用工作的最差比率之一,尽管其他解释器和工具(如 Cython)的行为会有所不同)并且,如果您使用更好的名称比 abc,更多的自记录代码。

预绑定 append 的副本而不是动态绑定有一些小好处(在最新版本的 Python 中减少了),所以如果您真的为了速度而受到伤害,尤其是在旧版本的 Python 没有优化绑定方法的创建,您可以尝试:

x = []
y = []
z = []
xapp, yapp, zapp = x.append, y.append, z.append
for a, b, c in zip(u, v, ind):
    if 0 < a < 1920 and 0 < b < 1080:
        xapp(a)
        yapp(b)
        zapp([c, c])

(如果需要,添加islice)以牺牲更丑陋的代码来减少方法调用开销。绝对不要这样做,除非分析表明这是热代码路径并且您真的需要它更快。

最后,请注意:如果此代码在顶层(在任何函数之外)运行,它的运行速度会明显变慢(函数中局部范围名称的变量查找是 C 数组查找;查找全局范围名称,函数外的所有查找都涉及到至少一个 dict 键查找,这要昂贵得多)。把它放在一个函数中(连同xyz的定义;uvind如果你是zipping而不是那么重要索引它们)并调用该函数而不是在全局范围内运行,它应该运行得更快。

使用numpy 数组而不是lists 可能会进行除此之外的改进,但您需要更具体地了解您的问题,才能冒险猜测此类更改的效用。

【讨论】:

  • 非常感谢。真的很赞!!
猜你喜欢
  • 1970-01-01
  • 2020-09-24
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
  • 2017-12-15
相关资源
最近更新 更多