如何使用ctype将列表列表的Python列表转换为C数组?

时间:2022-12-28 00:32:53

As seen here How do I convert a Python list into a C array by using ctypes? this code will take a python array and transform it to a C array.

如图所示,如何使用ctypes将Python列表转换为C数组?这段代码将使用python数组并将其转换为C数组。

import ctypes
arr = (ctypes.c_int * len(pyarr))(*pyarr)

Which would the way of doing the same with a list of lists or a lists of lists of lists?

用列表列表或列表列表列表来做同样的事情的方法是什么?

For example, for the following variable

例如,对于以下变量。

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]]]

I have tried the following with no luck:

我试过以下方法,但运气不好:

([[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

Thank you!

谢谢你!

EDIT: Just to clarify, I am trying to get one object that contains the whole multidimensional array, not a list of objects. This object's reference will be an input to a C DLL that expects a 3D array.

编辑:澄清一下,我试图获得一个包含整个多维数组的对象,而不是对象列表。这个对象的引用将是一个C DLL的输入,它需要一个3D数组。

2 个解决方案

#1


2  

It works with tuples if you don't mind doing a bit of conversion first:

如果你不介意先进行一些转换的话,它可以与元组一起工作:

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))

Check that it's initialized correctly in row-major order:

检查它是否按行主序正确初始化:

>>> (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]

Or you can create an empty array and initialize it using a loop. enumerate over the rows and columns of the list and assign the data to a slice:

或者您可以创建一个空数组并使用循环初始化它。枚举列表的行和列,并将数据分配给slice:

arr = (c_double * 4 * 2 * 3)()

for i, row in enumerate(list3d):
    for j, col in enumerate(row):
        arr[i][j][:] = col

#2


0  

I made the change accordingly

我做了相应的改变

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]

The arr_instance is what you want.

arr_instance是您想要的。

#1


2  

It works with tuples if you don't mind doing a bit of conversion first:

如果你不介意先进行一些转换的话,它可以与元组一起工作:

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))

Check that it's initialized correctly in row-major order:

检查它是否按行主序正确初始化:

>>> (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]

Or you can create an empty array and initialize it using a loop. enumerate over the rows and columns of the list and assign the data to a slice:

或者您可以创建一个空数组并使用循环初始化它。枚举列表的行和列,并将数据分配给slice:

arr = (c_double * 4 * 2 * 3)()

for i, row in enumerate(list3d):
    for j, col in enumerate(row):
        arr[i][j][:] = col

#2


0  

I made the change accordingly

我做了相应的改变

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]

The arr_instance is what you want.

arr_instance是您想要的。