如何在for循环中更改变量的名称

时间:2019-09-07 17:58:01

标签: julia

我想使用变量名中的循环索引在for循环中更改变量名。

我尝试了以下语法:

A= [1,2,3]
for i = 1:3
    global x{i}
    x{i}=A[i]
end

这不是正确的语法,并且使用谷歌搜索无法引导我使用正确的语法。

我也尝试过

A= [1,2,3]
for i = 1:3
    global x$i
    x$i=A[i]
end

我希望创建三个变量x1,x2和x3,每个变量都包含A的适当元素。也许我什至不需要编写循环来做到这一点-我愿意接受完全不同的方法也可以做到这一点。

3 个答案:

答案 0 :(得分:3)

正如其他人所说,是否应该这样做有点疑问,但是如果这确实是您想要做的,那么您可以这样做:

A = [1, 2, 3]
for i = 1:3
    @eval $(Symbol("x$i")) = $(A[i])
end

之后,将分配这些全局变量:

julia> x1, x2, x3
(1, 2, 3)

内部表达式等效于编写此代码:

eval(:($(Symbol("x$i")) = $(A[i])))

换句话说,您构造并评估赋值表达式,其中左侧是符号x$i,右侧是A[i]的值。

请注意,您只能像这样定义全局变量,而不能定义局部变量,因为eval始终在全局范围内操作。其他语言具有“本地评估”功能,Julia并不是因为某种语言中本地评估的可能性使优化变得更加困难。

答案 1 :(得分:1)

您只需执行import numpy as np from sklearn import linear_model from sklearn.linear_model import OrthogonalMatchingPursuit import matplotlib.pyplot as plt # accept x and polynomial order, return basis of that order def legs(x, c): s = np.zeros(c + 1) s[-1] = 1 return np.polynomial.legendre.legval(x, s) # Generate normalized samples samples = np.random.uniform(2, 3, 5) evals = samples ** 2 xnorm = (samples - 2) * 2 / (3 - 2) - 1 # instantiate linear regressor omp = linear_model.LinearRegression() #omp = linear_model.Lasso(alpha=0.000001) #omp = OrthogonalMatchingPursuit(n_nonzero_coefs=2) # construct X matrix. Each row is an observed value. # Each column is a different polynomial. X = np.array([[legs(xnorm[jj], ii) for ii in range(5)] for jj in range(xnorm.size)]) # Perform the fit. Why isn't this working? omp.fit(X, evals) # Plot the truth data plt.scatter(xnorm, evals, label='data', s=15, marker='x') # Dot the coefficients found with sklearn against X plt.scatter(xnorm, omp.coef_.dot(X.T), label='linear regression') # Dot the coefficients found with numpy against X plt.scatter(xnorm, np.polynomial.legendre.legfit(xnorm, evals, 4).dot(X.T), label='Numpy regression') # complete the plot plt.legend(ncol=3, prop={'size':3}) plt.savefig('simpleExample') plt.clf()

答案 2 :(得分:1)

简短的回答是,如果您不知道如何做,那肯定意味着您不需要它。就像DNF针对所有普通语言使用案例指出的那样,这绝对不是一个好习惯。

您正在寻找的功能可以通过元编程来完成。这是一个简单的示例代码(再次使用它,除非您已经对该语言有丰富的经验,并且现在想学习元编程,例如,因为您想在Julia之上构建自己的DSL):

macro definevars(name::String, a::Symbol, len::Int)
   res = :(;)
   for  i in 1:len
      varname = Symbol(string(name,i))
      push!(res.args, esc(:($varname = $a[$i])))
   end
   res
end

现在让我们对其进行测试:

julia> B = [5,6,7];


julia> @definevars "b" B 3;

julia> b1, b2, b3
(5, 6, 7)

这里有很多性能问题。您可能要结合使用StaticArrays@generated函数。