从数组列表中获取大量数组

时间:2011-02-01 12:20:03

标签: wolfram-mathematica

您好我正在使用Mathematica 5.2。假设我有一个像

这样的数组列表
    In[2]:=lst=Tuples[{0,1},4]

    Out[2]={{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},
            {0,1,0,0},{0,1,0,1},{0,1,1,0},{0,1,1,1},
            {1,0,0,0},{1,0,0,1},{1,0,1,0},{1,0,1,1},
            {1,1,0,0},{1,1,0,1},{1,1,1,0},{1,1,1,1}}

现在我想从上面的数组中获得16个数组,如st1 = {0,0,0,0}; st2 = {0,0,0,1},st3 = {0,0,1,0} ...... 如何使用循环获取这些数组列表。因为如果没有。上面名为lst的数组的元素变得越大,那么单独获取数组lst的每个元素并分别给出它们的名称将不是明智的决定。我尝试了以下方式,但它不起作用......

Do[st[i]=lst[[i]],{i,1,16}]

Plz有些身体在这个问题上帮助我...

5 个答案:

答案 0 :(得分:4)

它确实有用,但你创建的是所谓的indexed variables。您还应该使用索引访问它们,例如:

In[4]:= {st[1], st[2], st[3]}

Out[4]= {{0, 0, 0}, {0, 0, 1}, {0, 1, 0}}

答案 1 :(得分:3)

我认为你要做的事情可以通过以下方式完成:

lst = Tuples[{0, 1}, 4];
Table[Evaluate[Symbol["lst" <> ToString[i]]] = lst[[i]], {i, Length@lst}]  

那样

lst1 == {0,0,0,0} 

但这不是在Mathematica中管理变量的有用方法。

修改

我将尝试向您展示为什么变量lst1,lst2 ..没有用,并且反对“Mathematica方式”。

通过将函数应用于对象,Mathematica可以更好地工作。例如,假设您要使用EuclideanDistance。在R 4 中有一个点{1,2,3,4},并且您想要计算从您的集合到此点的最近点。

这很容易通过

完成
eds = EuclideanDistance[{1, 2, 3, 4}, #] & /@ Tuples[{0, 1}, 4]  

最近的点距离就是:

min = Min[eds]  

如果你想知道哪个点是最近的点,你可以这样做:

Select[lst, EuclideanDistance[{1, 2, 3, 4}, #] == min &]  

现在,尝试使用您预期的lst1,lst2 ..对象做同样的事情,你会发现它虽然不是不可能,却非常非常复杂。

修改

BTW,一旦你有了

lst = Tuples[{0, 1}, 4];  

只需输入

即可访问列表中的每个元素
lst[[1]]  

等。如果你需要循环。但同样,循环不是Mathematica方式。例如,如果您想获得另一个列表,并且元素已标准化,请不要循环,只需执行:

lstNorm = Norm /@ lst   

更清洁,更快捷
Do[st[i] = Norm@lst[[i]], {i, 1, 16}]

你会发现定义下行值(如上面的st [i])在求解方程式时很有用,但除了使用数组在其他语言中完成的许多操作之外,Mathematica中的操作最好通过使用列表来实现。

修改

回答您的评论actually I need each element of array lst to find the value of function such as f[x,y,z,k]=x-y+z+k。这样的功能可能是

 (#1 - #2 + #3 + #4) & @@@ lst  

 (#[[1]] - #[[2]] + #[[3]] + #[[4]]) & /@ lst  

出:

{0, 1, 1, 2, -1, 0, 0, 1, 1, 2, 2, 3, 0, 1, 1, 2}  

HTH!

答案 2 :(得分:2)

你可以这样做:

Table[
    Evaluate[
        Symbol["st" <> ToString@i]] = lst[[i]], 
            {i, 1, Length@lst}];

在最后尝试Names["st*"],看你现在已经定义了st1到st16。您也可以使用MapIndexed执行此操作,如下所示:

 MapIndexed[(Evaluate@Symbol["sts" <> ToString~Apply~#2] = #1) &, lst]

之后Names["sts*"]再次显示它已经有效。这两个都可以使用循环完成,如果这是你(但我不知道它买了什么)。

另一方面,这样,当您想要访问其中一个时,您需要执行Symbol["sts" <> ToString[4]]之类的操作。使用您已经完成的或类似的东西,例如,

Table[
Evaluate[stg[i]] = lst[[i]],{i, 1, Length@lst}]

你最终得到stg [1],stg [2]等,你可以通过例如Table[stg[i],{i,1,Length@lst}]

更容易地访问它们

您可以查看?stg定义的内容,或DownValues[stg]更详细的内容。

或者它是你想要的其他东西?

Leonid链接到一个教程,我建议你顺便读一读。

答案 3 :(得分:1)

N 这样做的方法,虽然像belisarius我对你的方法有疑问。尽管如此,我发现管理这类事情的最简单方法是使用Mathematica所称的"pure functions",如下所示:

In[1]:= lst = Tuples[{0,1}, 4];

In[2]:= With[{setter = (st[#1] = #2) &},
           Do[setter[i, lst[[i]]], {i, Length@lst}]];

这样做,特殊的评估规则就是你想要的。但是,我会在没有循环的情况下接近这个,只使用一个定义:

In[3]:= ClearAll[st] (* Clearing the existing definitions is important! *)

In[4]:= st[i_Integer] := lst[[i]]

我认为,如果您提供有关您要完成的内容的更多详细信息,我们将能够提供更多有用的建议。

编辑: Leonid Shifrin评论说,如果您在事后更改lst的定义,则更改也会影响st。你可以通过他描述的方式使用With来避免这种情况:

With[{rhs = lst}, 
  st[i_Integer] := rhs[[i]]];

我不知道哪些会对你要做的事情更有用,但无论哪种方式都是重要的。

答案 4 :(得分:0)

也许是这样的?

MapThread[Set, {Array[st, Length@lst], lst}];

例如:

{st[1], st[10], st[16]}

Out[14]= {{0, 0, 0, 0}, {1, 0, 0, 1}, {1, 1, 1, 1}}