【问题标题】:Python: Is it better to have many variables or to store their values in lists?Python:有很多变量还是将它们的值存储在列表中更好?
【发布时间】:2017-06-09 15:28:14
【问题描述】:

我知道这似乎是一个模糊的问题,但我想知道(例如在 Python 中)是否最好将多个值存储在单独的变量中,或者将它们存储在逻辑组中(列表、数组......) .

在我的确切情况下,我应该将 Matlab 代码翻译成 Python 2.7。它是一个基于物理的模型,可以消化 8 个输入变量并创建两个大列表作为输出。我发现原始模型有大量的变量在途中计算(> 100)。根据经验:如果一个计算被多次访问,它会存储在一个新变量中。示范例子:

x = 3
y = 5
x2 = x**2
z = x2 + exp(y)
zz = (y+x)/x2

x^2 使用了两次(用于计算 z 和 zz),所以存储为 x2。这真的比让 python 计算 x**2 两次更快吗?另外,如果我将它们存储在列表中会更快吗?像这样:

x = [3, 5]
z = x[0]**2 + exp(x[1])
zz = sum(x)/x[0]**2

列表中变量的组织可能会牺牲代码的可读性,但如果它能让我的代码运行得更快,我会很乐意接受。

【问题讨论】:

  • 你有密码;分析它并查看。

标签: performance python-2.7 list variables


【解决方案1】:

我认为将其保留在列表中没有性能优势。相反,将其放在列表中会使其变慢:

>>>  %%timeit
...: x = 3
...: y = 5
...: x2 = x**2
...: z = x2 + exp(y)
...: zz = (y+x)/x2
...: 
337 ns ± 1.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

>>>  %%timeit
...: x = [3, 5]
...: z = x[0]**2 + exp(x[1])
...: zz = sum(x)/x[0]**2
...: 
716 ns ± 4.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

现在部分原因是您在列表条件下计算 x**2 两次,但即使修复该问题也不会使列表版本更快:

>>>  %%timeit
...: x = [3, 5]
...: x0 = x[0]**2
...: z = x0 + exp(x[1])
...: zz = sum(x)/x0
...: 
502 ns ± 12.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

如果您比较性能,另一个大问题是您定义整数然后将它们转换为浮点数。在 MATLAB 中,x = 5 生成一个浮点数,而在 python 中它生成一个整数。从一开始就使用浮点数做所有事情要快得多,您只需在数字末尾添加 ..0 即可:

>>>  %%timeit
...: x = 3.0
...: y = 5.0
...: x2 = x**2.0
...: z = x2 + exp(y)
...: zz = (y+x)/x2
...: 
166 ns ± 1.12 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

如果你要使用 numpy 数组而不是列表,那就更糟了,因为你从浮点数列表开始,然后必须对数字和列表进行转换,然后再将它们转换回来,所有这些都是慢:

>>> %%timeit
...: x = np.array([3., 5.])
...: x0 = x[0]**2.
...: z = x0 + np.exp(x[1])
...: zz = x.sum()/x0
...: 
3.22 µs ± 8.96 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

作为一般规则,应尽可能避免进行类型转换,并在不利于可读性的情况下避免索引。如果您有一堆值,那么转换为 numpy 很有用。但是对于两三个人来说,它会影响速度和可读性。

【讨论】:

  • 精彩的回答,谢谢!我记得有人说 numpy 在数学任务中速度更快,所以我尽可能避免使用列表。我会注意所有的浮点数都将被初始化。目前,在 FORTRAN 中运行 1000 个模型需要 5.5 秒,在 MATLAB 中需要 10.3 秒,在我的 PYTHON 代码中需要 11.2 秒。将不得不改善这一点。所以,再次感谢:)
  • @offeltoffel:如果我的答案是您所需要的,请将其标记为回答您的问题,以便其他人可以轻松找到它。
猜你喜欢
  • 2011-03-23
  • 2016-12-03
  • 1970-01-01
  • 1970-01-01
  • 2021-01-22
  • 1970-01-01
  • 1970-01-01
  • 2014-05-17
  • 1970-01-01
相关资源
最近更新 更多