对于此示例,我有一个包含变量名称的文件,例如 foo 或 bar[4][5],其中的名称可能有也可能没有可变数量的索引,因为变量可能是多维数组。字典里面还有每个变量的起始内存地址,以及它的值类型,例如int_32或signed_int_64等。
我的程序应该打印出每个变量,任何数组的每个组件,它的内存地址和它的值。问题是,我该如何处理数组?它们可以是一维的、二维的、十二维的,甚至是零维的(单值),但我需要用一个程序来获得它们。另一个重要因素是使程序足够健壮,可以承受任意数量的维度。
我的解决方案是获取名称并检查它是否与 stackoverflow 的另一个用户提供的正则表达式匹配。以下代码应归功于 Lib。
def getEntryName(var_string) : # From LIB @ Stackoverflow.com
result = re.search(r'(.*?)((?:\[\d*])*)$', var_string)
var_name = result.group(1)
numbers = re.findall(r'\[(\d+)]', result.group(2))
return var_name, numbers
这将返回一个变量的基本名称和一个名为“numbers”的列表,其中包含所有数组的所有索引。
现在我使用递归调用来查找迭代任意数量的索引!
def BracketHandler( PassedRange, var_name, var_Length, var_startA, numbers )
for i in range( 0, int( PassedRange ) - 1 ) : # We cycle through it!
if numbers : # If there are more indexes to cycle through,
BracketHandler( numbers[0], var_name + "[" + str( i ) + "]",
var_Length, var_startA, numbers[1:] )
else: # Exit Condition
ProcessVar(var_name + "[" + str( i ) + "]",
var_Length, var_startA) var_startA += var_length
现在解释我的代码。基本上,在运行这个函数之前,我检查以确保数字中有任何内容,如果有,我将这个递归函数传递给数字中的第一个值、变量的名称、长度和起始地址,最后是其余的数字 ( which mich be = []) 在那里,我遍历当前索引。接下来我检查集合中是否还有更多数字,如果有,我将当前索引附加到名称上,然后再次运行该函数,直到没有新数字为止。
这时,没有新的数字,我在另一个函数中处理变量,并增加起始地址。还有中提琴!
如果此代码采用 foo 之类的名称和 [4, 6, 8] 之类的一组数字,它将产生:
foo[0][0][0]
foo[0][0][1]
...
foo[0][0][7]
foo[0][1][0]
...
foo[3][5][7]
并将它们全部发送给以正确的值进行处理!
可能有更好的解决方案,但我找不到任何解决方案。我对此进行了很长一段时间的修改,以使其尽可能地发挥作用,虽然这对某些人来说似乎很明显,但在当时却不那么明显。如果您有任何改进的建议,我欢迎。如果我所做的有任何错误,请随时编辑我的错误。如果这不是进行问答的适当方式,请告诉我,我将删除它!
另一种可能性是在这里使用itertools.product而不是递归来获取所有坐标。对于 (say) 的数量[1,3,4]
,您基本上想要笛卡尔积[0] x [0,1,2] x [0,1,2,3]
,而这正是itertools.product
:
例如:
>>> from itertools import product
>>> numbers = [1, 3, 4]
>>> product(*(range(n) for n in numbers))
<itertools.product object at 0x101abb640>
>>> list(product(*(range(n) for n in numbers)))
[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 1, 3), (0, 2, 0), (0, 2, 1), (0, 2, 2), (0, 2, 3)]
(记住这f(*(a,b,c))
基本上是f(a,b,c)
。)
将整个东西包装成一个生成器:
def all_coords(name, numbers):
coords = product(*(range(n) for n in numbers))
for coord in coords:
yield name + ''.join('[{}]'.format(c) for c in coord)
这会给我们
>>> list(all_coords("foo", [2,2]))
['foo[0][0]', 'foo[0][1]', 'foo[1][0]', 'foo[1][1]']
>>> for x in all_coords("foo", [2,2]):
... print x
...
foo[0][0]
foo[0][1]
foo[1][0]
foo[1][1]
使用np.ndenumerate
. 例如:
for ind,value in np.ndenumerate(myarray):
print ind, value
将循环遍历作为元组给出ind
的数组,这将(i,)
用于一维数组、(i,j)
2D、(i,j,k)
3D 等等......,您可以访问始终从数组中检索的数据,例如:
`myarray[ind]`
允许您对任何数组进行一般循环...