Numba: Creando una tupla a partir de una lista
Tengo un problema muy simple que no puedo resolver.
Estoy utilizando Numba y Cuda.
Tengo una lista T=[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0] y quiero una tupla con los elementos de la lista, así:
C=(1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0).
En Python usaría C=tuple(T), pero no puedo con Numba.
He intentado estas soluciones pero ninguna de ellas funciona porque no se puede modificar el tipo de una variable dentro de un bucle con Numba.
Importante Mi lista tiene una longitud que es múltiplo de 3 y utilizo este conocimiento para mis algoritmos.
Código
Primer algoritmo, de forma recursiva, funciona mediante el uso de L=[(1.0,),(2.0,),(3.0,),(4.0,),(5.0,),…,(9.0,)]
@njit
def list2tuple(L):
n=len(L)
if n == 1:
return L[0]
else:
C=[]
for i in range(0,n-2,3):
c=L[i]+L[i+1]+L[i+2]
C.append(c)
return list2tuple(C)
Problema: Entra en un bucle infinito y debo detener el núcleo. Funciona en Python básico.
Algoritmo 2: funciona al dar T=[1.0,2.0,3.0,…,9.0]
@njit
def list2tuple2(T):
L=[]
for i in range(len(T)):
a=(T[i],)
L.append(a)
for k in range(len(T)//3-1):
n=len(L)
C=[]
for j in range(0,n-2,3):
c=L[j]+L[j+1]+L[j+2]
C.append(c)
L=C
return L[0]
Problema: Cuando C=[(1.0,2.0,3.0),(4.0,5.0,6.0),(7.0,8.0,9.0)], no se puede decir L=C porque L=[(1.0,),(2.0,),(3.0,),….(9.0,)] es List(Unituple(float64x1)) y no se puede unificar con List(Unituple(float64x3)).
No puedo encontrar una solución para este problema.
davy.ai
Desafortunadamente, Numba no admite convertir una lista en una tupla directamente como lo harías con la función
tuple()
de Python. Sin embargo, hay un truco que puedes intentar.Una solución podría ser definir explícitamente el tamaño de la tupla de salida y copiar manualmente los elementos de la lista en la tupla. Por ejemplo, asumiendo que la longitud de la lista siempre es un múltiplo de 3, podrías hacer algo como esto:
Aquí, primero creamos un array de numpy vacío llamado
C
con el dtype correcto (‘f8,f8,f8’ para una tupla de 3 floats de 64 bits) y el tamaño correcto (n // 3 para una lista de longitud n que es un múltiplo de 3). Luego, recorremos la listaT
en pasos de 3 y copiamos los elementos en la posición correspondiente de la tuplaC
. Finalmente, retornamos una tupla del array completoC
.Ten en cuenta que esta solución requiere el uso de arrays de numpy en lugar de listas. Si no puedes usar numpy, podrías considerar escribir una clase personalizada para el tipo
tuple
que admita agregar o modificar elementos, pero esto puede no ser una tarea trivial.