如何在 IDL FOR 循环中标记输出变量以便在同一程序的循环外进行进一步处理?

发布于 2024-10-16 11:26:57 字数 321 浏览 2 评论 0原文

我有一个像这样的 FOR 循环:

FOR k = 1,216 DO  atom = G[*,0:*:(215+k)]  END

我希望能够做的是将每个原子的数组(例如,atom_k)存储在内存中,然后调用这些不同的变量以在 FOR 循环之外执行进一步的操作。 从概念上讲,我想用“k”计数器来标记“atom”变量,有点像这样:

FOR k = 1,216 DO  atom(k) = G[*,0:*:(215+k)]  END

当然,这不起作用,因为在这种情况下“k”不再是标签。有谁知道吗?

I have a FOR loop like this:

FOR k = 1,216 DO  atom = G[*,0:*:(215+k)]  END

What I would like to be able to do is to store in memory the array for each atom, say, atom_k and then call these different variables to perform further operations outside the FOR loop.
Conceptually, I want to label the "atom" variable with the "k" counter somewhat like this:

FOR k = 1,216 DO  atom(k) = G[*,0:*:(215+k)]  END

Of course, this doesn't work because "k" is no longer a label in this case. Does anyone know?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

能否归途做我良人 2024-10-23 11:26:57

我假设您谈论的是 IDL,ITTVis 开发的语言。
我不明白你索引 G 或 END 指令的方式,但我不使用最新版本。

尝试执行命令。这允许您在运行时执行语句。

FOR k = 1,216 DO status = EXECUTE('atom_'+strtrim(k,2)+' = G[,0::(215+'+strtrim(k,2)+')]') END

STRTRIM 将整数转换为不带空格的字符串。

I assume you're talking of IDL, the language developped by ITTVis.
I don't understand the way you index G nor the END instruction, but I'm not working with latest version.

Try the EXECUTE command. This allows you execute statements at runtime.

FOR k = 1,216 DO status = EXECUTE('atom_'+strtrim(k,2)+' = G[,0::(215+'+strtrim(k,2)+')]') END

STRTRIM converts integers to string without blanks around.

厌倦 2024-10-23 11:26:57

看起来您正在尝试创建一个参差不齐的数组。您想要的是像列表列表一样的数据结构,其中子列表具有不同数量的元素。这是与版本相关的,但看起来 8 中引入的 list() 函数会正是这样做。

atoms = list()
FOR k = 1,216 DO  atoms.add, G[*,0:*:(215+k)]  END

我实际上并不肯定 list() 是创建空列表的正确方法。无法调试它,因为我没有运行 8。

Looks like you're trying to create a ragged array. What you want is a data structure like a list of lists, where the sublists have a different number of elements. This is version-dependent, but it looks like the list() function introduced in 8 would do exactly this.

atoms = list()
FOR k = 1,216 DO  atoms.add, G[*,0:*:(215+k)]  END

I'm actually not positive that list() is the proper way to create an empty list. Can't debug it because I'm not running 8.

倥絔 2024-10-23 11:26:57

我知道有几个选项:

在以下选项中,#1 最接近您的要求,但我相信 #3 为您提到的目标、速度以及与不同版本的兼容性提供了最佳的可用性组合。 IDL。

1) 使用 scope_varfetch/enter< /code> 关键字:

pro foo, G
    for k = 1, 216 do begin
        varname = 'atom' + strtrim(k, 1)
        (scope_varfetch(varname, level=-1, /enter)) = G[*, 0:*:(215 + k)]
    endfor
end

这会在调用例程中创建名为 atom1atom216 的变量,或者在 $MAIN$ 中(如果以交互方式执行)。我认为这最接近您的要求。您还可以使用 print,atom5 等语法,通过名称直接从调用函数访问这些变量:

for k = 1, 216 do begin
    varname = 'atom' + strtrim(k, 1)
    print, scope_varfetch(varname)
endfor

2) 使用 IDL 8.0+ List 对象:

atom = list(length=216)
for k = 0, 215 do atom[k] = G[*, 0:*:(216 + k)]

请注意,该列表是 0 索引的,这意味着第一个元素为零,而不是一。使用atom[0] 访问第一个原子,依此类推。要访问第一个原子的第一个索引,请用括号括起来,并使用一组附加的括号进行索引:(atom[0])[0, 0]。由于 IDL 不寻常的操作顺序,括号是必需的。

3)使用指针数组:

atom = ptrarr(216)
for k = 0, 215 do atom[k] = ptr_new(G[*, 0:*:(216 + k)])

或者使用稍微不同的语法:

atom = ptrarr(216, /allocate_heap)
for k = 0, 215 do *atom[k] = ptr_new(G[*, 0:*:(216 + k)])

这是最有效且高度兼容的方法。指针以及相关的 ptrarr 和 ptr_new 函数自 IDL 5.0 起就已存在,它们比列表、哈希或scope_varfetch 高效得多。
请注意,与列表一样,它也是从 0 索引的。此外,要访问这些值,您必须使用 * 来“引用”它们,如 print、*atom[0] 来打印第一个原子数组,或者 print, (*atom[0])[0, 0] 打印第一个数组的第一个元素,依此类推。需要括号的原因与列表相同。也可以使用 (*atom[0])[1, 15] = new_values 等语法来设置值。

4) 使用 IDL 8.0+ 哈希:

atoms = hash()
for k = 1, 216 do begin
    name = 'atom' + strtrim(k, 1)
    atoms[name] = G[*, 0:*:(215 + k)]
endfor

可以像 atoms['atom0'] 一样引用它们。我认为在这种情况下这可能不是最好的选择,因为数组效率更高,但如果需要使用其他字符串名称,或者数据索引稀疏,则它非常有用。

5) 使用 create_struct 构建结构:

atoms = !null
for k = 1, 216 do begin
    tagname = 'atom' + strtrim(k, 1)
    atoms = create_struct(atoms, tagname, G[*, 0:*:(215 + k)])
endfor

这是非常慢,但是一旦完成就相对容易理解。获取每个数组(如atoms.atom1)并获取一个元素(如atoms.atom1[0, 0])。

There are a few options I'm aware of:

Of the following, #1 is the closest to what you requested, but I believe that #3 offers the best blend of usability for your mentioned goal, speed, and compatibility with different versions of IDL.

1) Using scope_varfetch with the /enter keyword:

pro foo, G
    for k = 1, 216 do begin
        varname = 'atom' + strtrim(k, 1)
        (scope_varfetch(varname, level=-1, /enter)) = G[*, 0:*:(215 + k)]
    endfor
end

This creates variables named atom1 through atom216 in the calling routine, or in $MAIN$ if executed interactively. I think this is the closest to what you requested. You can also access those variables directly from the calling function by name using syntax either like print, atom5 or like:

for k = 1, 216 do begin
    varname = 'atom' + strtrim(k, 1)
    print, scope_varfetch(varname)
endfor

2) Using an IDL 8.0+ List object:

atom = list(length=216)
for k = 0, 215 do atom[k] = G[*, 0:*:(216 + k)]

Note that the list is 0-indexed, meaning that the first element is zero, instead of one. Use atom[0] to access the first atom, and so on. To access the first index of the first atom, surround with parentheses and use an additional set of brackets to index: (atom[0])[0, 0]. The parentheses are necessary due to IDL's unusual order of operations.

3) Using a pointer array:

atom = ptrarr(216)
for k = 0, 215 do atom[k] = ptr_new(G[*, 0:*:(216 + k)])

Or with slightly different syntax:

atom = ptrarr(216, /allocate_heap)
for k = 0, 215 do *atom[k] = ptr_new(G[*, 0:*:(216 + k)])

This is the most efficient and highly compatible way to do it. Pointers and the associated ptrarr and ptr_new functions have been around since IDL 5.0, and they are much more efficient than lists, hashes, or scope_varfetch.
Note that like the list, this is 0-indexed. Also, to access these values you have to "deference" them with a *, as in print, *atom[0] to print the first atom array, or print, (*atom[0])[0, 0] to print the first element of the first array and so on. The parentheses are required for the same reason as with the list. Setting values is also possible with syntax like (*atom[0])[1, 15] = new_values.

4) Using an IDL 8.0+ hash:

atoms = hash()
for k = 1, 216 do begin
    name = 'atom' + strtrim(k, 1)
    atoms[name] = G[*, 0:*:(215 + k)]
endfor

These can be referenced like atoms['atom0']. I don't think this is probably the best option in this case, since an array is more efficient, but it is very useful if there are additional string names you need to use, or if the data indexes are sparse.

5) Building a structure with create_struct:

atoms = !null
for k = 1, 216 do begin
    tagname = 'atom' + strtrim(k, 1)
    atoms = create_struct(atoms, tagname, G[*, 0:*:(215 + k)])
endfor

This is very slow, but relatively easy to understand once it's done. Get each array like atoms.atom1 and get an element like atoms.atom1[0, 0].

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文