如此处所示 如何使用 ctypes 将 Python 列表转换为 C 数组? 此代码将采用 Python 数组并将其转换为 C 数组。
import ctypes
arr = (ctypes.c_int * len(pyarr))(*pyarr)
对于列表的列表或列表的列表的列表,哪种方法可以做同样的事情?
例如,对于以下变量
list3d = [[[40.0, 1.2, 6.0, 0.3], [50.0, 4.2, 0, 0]], [[40.0, 1.2, 6.0, 0.3], [50.0, 4.2, 0, 0]], [[40.0, 1.2, 6.0, 0.3], [50.0, 4.2, 0, 0]]]
我尝试了以下方法,但没有成功:
([[ctypes.c_double * 4] *2]*3)(*list3d)
# *** TypeError: 'list' object is not callable
(ctypes.c_double * 4 *2 *3)(*list3d)
# *** TypeError: expected c_double_Array_4_Array_2 instance, got list
谢谢!
编辑:只是为了澄清一下,我试图获取一个包含整个多维数组的对象,而不是对象列表。该对象的引用将是需要 3D 数组的 C DLL 的输入。
它适用于元组如果你不介意先做一些转换:
from ctypes import *
list3d = [
[[0.0, 1.0, 2.0, 3.0], [4.0, 5.0, 6.0, 7.0]],
[[0.2, 1.2, 2.2, 3.2], [4.2, 5.2, 6.2, 7.2]],
[[0.4, 1.4, 2.4, 3.4], [4.4, 5.4, 6.4, 7.4]],
]
arr = (c_double * 4 * 2 * 3)(*(tuple(tuple(j) for j in i) for i in list3d))
检查它是否按行优先顺序正确初始化:
>>> (c_double * 24).from_buffer(arr)[:]
[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0,
0.2, 1.2, 2.2, 3.2, 4.2, 5.2, 6.2, 7.2,
0.4, 1.4, 2.4, 3.4, 4.4, 5.4, 6.4, 7.4]
或者您可以创建一个空数组并使用循环对其进行初始化。
enumerate
覆盖 list
的行和列并将数据分配给切片:
arr = (c_double * 4 * 2 * 3)()
for i, row in enumerate(list3d):
for j, col in enumerate(row):
arr[i][j][:] = col
我做了相应的改变
a = [[[40.0, 1.2, 6.0, 0.3], [50.0, 4.2, 0, 0]], [[40.0, 1.2, 6.0, 0.3], [50.0, 4.2, 0, 0]], [[40.0, 1.2, 6.0, 0.3], [50.0, 4.2, 0, 0]]]
arr = (((ctypes.c_float * len(a[0][0])) * len(a[0])) * len(a))
arr_instance=arr()
for i in range(0,len(a)):
for j in range(0,len(a[0])):
for k in range(0,len(a[0][0])):
arr_instance[i][j][k]=a[i][j][k]
arr_instance
就是你想要的。
我想要一个更通用和更明确的解决方案,所以我编写了这个递归函数,让我可以创建任意维度的列表。
import ctypes
def flatten_into_ctypes(l, ctype):
result = []
for i in l:
if type(i) is list:
result = result + (flatten_into_ctypes(i, ctype))
else:
result.append(ctype(i))
return(result)
运行示例:
list3d = [
[[0.0, 1.0, 2.0, 3.0], [4.0, 5.0, 6.0, 7.0]],
[[0.2, 1.2, 2.2, 3.2], [4.2, 5.2, 6.2, 7.2]],
[[0.4, 1.4, 2.4, 3.4], [4.4, 5.4, 6.4, 7.4]],
]
out = flatten_into_ctypes(list3d, ctypes.c_double)
>>> out
[c_double(0.0), c_double(1.0), c_double(2.0), c_double(3.0),
c_double(4.0), c_double(5.0), c_double(6.0), c_double(7.0),
c_double(0.2), c_double(1.2), c_double(2.2), c_double(3.2),
c_double(4.2), c_double(5.2), c_double(6.2), c_double(7.2),
c_double(0.4), c_double(1.4), c_double(2.4), c_double(3.4),
c_double(4.4), c_double(5.4), c_double(6.4), c_double(7.4)]