I have some python code that I wrote to convert a python list into an XML element. It's meant for interacting with LabVIEW, hence the weird XML array format. Anyways, here's the code:
我有一些python代码,我写了将python列表转换为XML元素。它用于与LabVIEW交互,因此是奇怪的XML数组格式。无论如何,这是代码:
def pack(data):
# create the result element
result = xml.Element("Array")
# report the dimensions
ref = data
while isinstance(ref, list):
xml.SubElement(result, "Dimsize").text = str(len(ref))
ref = ref[0]
# flatten the data
while isinstance(data[0], list):
data = sum(data, [])
# pack the data
for d in data:
result.append(pack_simple(d))
# return the result
return result
Now I need to write an unpack() method to convert the packed XML Array back into a python list. I can extract the array dimensions and data just fine:
现在我需要编写一个unpack()方法来将打包的XML Array转换回python列表。我可以很好地提取数组维度和数据:
def unpack(element):
# retrieve the array dimensions and data
lengths = []
data = []
for entry in element:
if entry.text == "Dimsize":
lengths.append(int(entry.text))
else:
data.append(unpack_simple(entry))
# now what?
But I am not sure how to unflatten the array. What would be an efficient way to do that?
但我不知道如何解开阵列。什么是有效的方法呢?
Edit: Here's what the python list and corresponding XML looks like. Note: the arrays are n-dimensional.
编辑:这是python列表和相应的XML的样子。注意:数组是n维的。
data = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
And then the XML version:
然后是XML版本:
<Array>
<Dimsize>2</Dimsize>
<Dimsize>2</Dimsize>
<Dimsize>2</Dimsize>
<I32>
<Name />
<Val>1</Val>
</I32>
... 2, 3, 4, etc.
</Array>
The actual format isn't important though, I just don't know how to unflatten the list from:
实际的格式并不重要,我只是不知道如何从列表中取消:
data = [1, 2, 3, 4, 5, 6, 7, 8]
back into:
data = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
given:
lengths = [2, 2, 2]
Assume pack_simple() and unpack_simple() do the same as pack() and unpack() for the basic data types (int, long, string, boolean).
假设pack_simple()和unpack_simple()对pack()和unpack()执行与基本数据类型(int,long,string,boolean)相同的操作。
2 个解决方案
#1
2
Try the following:
请尝试以下方法:
from operator import mul
def validate(array, sizes):
if reduce(mul, sizes) != len(array):
raise ValueError("Array dimension incompatible with desired sizes")
return array, sizes
def reshape(array, sizes):
for s in sizes:
array = [array[i:i + s] for i in range(0, len(array), s)]
return array[0]
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
length = [2, 2, 3]
print reshape(validate(data, length))
length = [2, 2, 2]
print reshape(validate(data, length))
Output being:
[[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]]
Traceback:
(...)
ValueError: Array dimension incompatible with desired sizes
An alternative is using numpy
arrays. Note that for this simple task, numpy is a rather big dependency, though you will find that most (common) array related tasks/problems already have an implementation there:
另一种方法是使用numpy数组。请注意,对于这个简单的任务,numpy是一个相当大的依赖,但你会发现大多数(常见的)数组相关的任务/问题已经在那里有一个实现:
from numpy import array
print array(data).reshape(*length) # optionally add .tolist() to convert to list
EDIT: Added data validation
编辑:添加数据验证
EDIT: Example using numpy arrays (thanks to J.F.Sebastian for the hint)
编辑:使用numpy数组的示例(感谢J.F.Sebastian提示)
#2
2
start inside out:
从里到外:
def group(seq, k):
return [seq[i:i+k] for i in range(0, len(seq), k)]
unflattened = group(group(data, 2), 2)
Your example might be easier, if your dimensions were not all the same. But I think the above code should work.
如果您的尺寸不尽相同,那么您的示例可能会更容易。但我认为上面的代码应该有效。
#1
2
Try the following:
请尝试以下方法:
from operator import mul
def validate(array, sizes):
if reduce(mul, sizes) != len(array):
raise ValueError("Array dimension incompatible with desired sizes")
return array, sizes
def reshape(array, sizes):
for s in sizes:
array = [array[i:i + s] for i in range(0, len(array), s)]
return array[0]
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
length = [2, 2, 3]
print reshape(validate(data, length))
length = [2, 2, 2]
print reshape(validate(data, length))
Output being:
[[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[9, 10], [11, 12]]]
Traceback:
(...)
ValueError: Array dimension incompatible with desired sizes
An alternative is using numpy
arrays. Note that for this simple task, numpy is a rather big dependency, though you will find that most (common) array related tasks/problems already have an implementation there:
另一种方法是使用numpy数组。请注意,对于这个简单的任务,numpy是一个相当大的依赖,但你会发现大多数(常见的)数组相关的任务/问题已经在那里有一个实现:
from numpy import array
print array(data).reshape(*length) # optionally add .tolist() to convert to list
EDIT: Added data validation
编辑:添加数据验证
EDIT: Example using numpy arrays (thanks to J.F.Sebastian for the hint)
编辑:使用numpy数组的示例(感谢J.F.Sebastian提示)
#2
2
start inside out:
从里到外:
def group(seq, k):
return [seq[i:i+k] for i in range(0, len(seq), k)]
unflattened = group(group(data, 2), 2)
Your example might be easier, if your dimensions were not all the same. But I think the above code should work.
如果您的尺寸不尽相同,那么您的示例可能会更容易。但我认为上面的代码应该有效。