es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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.

Tags:  , ,

Answer

  1. Avatar for 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:

    from numba import cuda, njit
    import numpy as np
    
    @njit
    def list2tuple(T):
        n = len(T)
        C = np.empty(n // 3, dtype=np.dtype('f8,f8,f8'))
        for i in range(0, n, 3):
            C[i // 3] = T[i], T[i+1], T[i+2]
        return tuple(C)
    

    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 lista T en pasos de 3 y copiamos los elementos en la posición correspondiente de la tupla C. Finalmente, retornamos una tupla del array completo C.

    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.

Comments are closed.