我有一个这样的 FOR 循环:
FOR k = 1,216 DO atom = G[*,0:*:(215+k)] END
我想做的是将每个原子的数组存储在内存中,例如 atom_k ,然后调用这些不同的变量以在 FOR 循环之外执行进一步的操作。从概念上讲,我想用“k”计数器标记“原子”变量,有点像这样:
FOR k = 1,216 DO atom(k) = G[*,0:*:(215+k)] END
当然,这不起作用,因为在这种情况下“k”不再是标签。有人知道吗?
我有一个这样的 FOR 循环:
FOR k = 1,216 DO atom = G[*,0:*:(215+k)] END
我想做的是将每个原子的数组存储在内存中,例如 atom_k ,然后调用这些不同的变量以在 FOR 循环之外执行进一步的操作。从概念上讲,我想用“k”计数器标记“原子”变量,有点像这样:
FOR k = 1,216 DO atom(k) = G[*,0:*:(215+k)] END
当然,这不起作用,因为在这种情况下“k”不再是标签。有人知道吗?
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.
我假设您说的是 IDL,这是 ITLVis 开发的语言。我不明白你索引 G 的方式和 END 指令,但我没有使用最新版本。
尝试执行命令。这允许您在运行时执行语句。
FOR k = 1,216 DO status = EXECUTE('atom_'+strtrim(k,2)+' = G[,0::(215+'+strtrim(k,2)+')]') END
STRTRIM 将整数转换为不带空格的字符串。
我知道有几个选项:
在以下各项中,#1 最接近您的要求,但我相信#3 为您提到的目标、速度和与不同版本的 IDL 的兼容性提供了最佳的可用性组合。
1)scope_varfetch
与/enter
关键字一起使用:
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
这会在调用例程中创建名为atom1
through的变量,或者在交互式执行时创建变量。我认为这是最接近您要求的。您还可以使用类似或类似的语法直接从调用函数中访问这些变量:atom216
$MAIN$
print, atom5
for k = 1, 216 do begin
varname = 'atom' + strtrim(k, 1)
print, scope_varfetch(varname)
endfor
2) 使用 IDL 8.0+列表对象:
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)])
这是最有效和高度兼容的方式。自 IDL 5.0 以来,指针和相关的ptrarr
函数ptr_new
就已经存在,它们比列表、散列或scope_varfetch
. 请注意,与列表一样,它是 0 索引的。此外,要访问这些值,您必须使用 a 来“尊重”它们*
,例如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
这很慢,但是一旦完成就相对容易理解。获取每个数组 likeatoms.atom1
并获取一个元素 like atoms.atom1[0, 0]
。