我正在尝试重写一些看起来像是由 FORTRAN 程序员编写的代码,以使其更具 Python 风格/可读性。下面是感兴趣的代码片段。代码的总体行为是,只要 Z 的值小于 1,就将 Z 的前三个元素存储到 Zstart 中,并且只要 Z 的后三个值小于 1,也将它们存储到 Zend 中。
import numpy as np
nbpoints = 3
Z = np.linspace(0,1.0,10)
Zstart = np.ones(nbpoints)
Zend = np.ones(nbpoints)
Zpts = np.size(Z)
for j in range(nbpoints):
if Z[j] < Zstart[j]:
Zstart[j] = Z[j]
if Z[Zpts - 1 - j] < Zend[nbpoints - 1 - j]:
Zend[nbpoints - 1 - j] = Z[Zpts - 1 - j]
从两端反向移动 Zstart 和 Zend 的访问让我有点困惑。我当前的解决方案如下。
import numpy as np
nbpoints = 3
Z = np.linspace(0,1.0,10)
Zstart = np.ones(nbpoints)
Zend = np.ones(nbpoints)
Zpts = np.size(Z)
for j in range(nbpoints):
if Z[j] < Zstart[j]:
Zstart[j] = Z[j]
if Z[-(j+1)] < Zend[-(j+1)]:
Zend[-(j+1)] = Z[-(j+1)]
此代码的示例输出是:
Z = [ 0.0 0.11111111 0.22222222 0.33333333 0.44444444 0.55555556
0.66666667 0.77777778 0.88888889 1.0 ]
Zstart = [ 0.0 0.11111111 0.22222222]
Zend = [ 0.77777778 0.88888889 1.0 ]
我的解决方案感觉就像我仍然只是重写写得不好的代码,例如重新安排泰坦尼克号甲板上的椅子。有没有更Pythonic的方式来执行这个操作?
最佳答案
您不需要使用 np.ones
实例化 Zstart
和 Zend
。只需直接构建它们即可:
nbpoints = 3
Z = np.linspace(0,1.0,10)
Zstart = Z[:nbpoints][Z[:nbpoints] < 1]
Zend = Z[-nbpoints:][Z[-nbpoints:] < 1]
print(Zstart)
print(Zend)
# [ 0. 0.11111111 0.22222222]
# [ 0.77777778 0.88888889]
请注意,Zend
这里只有 2 个元素,因为 Z
中的最后一个元素不小于 1。
关于以相反顺序访问 numpy 数组的 Pythonic 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46713489/