Dos implementaciones Python3 de bucles dinámicos, capas indefinidas de bucles (bucles recursivos y puros)

'' ' 
Los bucles dinámicos son dos implementaciones de Python3 de número indefinido de bucles (recursivo, bucle puro) 

# Nota: Python solo tiene un tipo de lista de forma predeterminada, y se puede entender como una matriz de C. 
# Para tomar 3 elementos de las siguientes 3 matrices para formar uno, e imprimir las posibles combinaciones de 
datos = [ 
    [1, 2], 
    [3, 4, 5], 
    [6, 7, 8, 9] 
] 
# Significa que habrá 2 * 3 * 4 = 24 posibilidades, es decir, el producto Deca de todas las listas. La solución se puede realizar con un bucle triple. Por ejemplo: 
para i en datos [0]: 
    para j en datos [1]: 
        para k en data [2]: 
            print ([i, j, k]) 

Pero si el número de matrices en los datos es incierto, ¿qué sucede si implementamos un bucle dinámico de capa indefinida? 
Pienso en los datos como una matriz bidimensional: la 
primera dimensión es la cantidad de datos que contiene la matriz, es decir, el eje Y, comenzando desde 0 y aumentando de arriba a abajo; la 
segunda dimensión es la cantidad de elementos contenidos en cada matriz, es decir, el eje X , Comenzando en 0 y aumentando columna por columna de izquierda a derecha; 
luego procese los dos ejes X e Y con métodos de bucle recursivo y puro, respectivamente. 
'' ' 

' '' 
Método recursivo 
Desde la primera capa del eje Y, es decir, índice = 0, recursivamente de arriba hacia abajo. Cuando se alcanza la capa inferior, se usa un bucle para agregar un elemento de la capa inferior a la lista que se devolverá cada vez. 
Nota: Python tiene un límite en el número de capas recursivas, y el número límite de diferentes sistemas operativos no es el mismo, es necesario considerar otro algoritmo cuando está por encima de 100 capas. 
'' '
# fuente de datos de datos, cur_y_idx valor actual del eje Y, lst_rst devuelve la lista de resultados, lst_tmp se usa para ensamblar temporalmente elementos de 
lst_rst def dynloop_rcsn (data, cur_y_idx = 0, lst_rst = [], lst_tmp = []): 
    max_y_idx = len (data) -1 # Obtener el valor de índice máximo del eje Y 
    para x_idx en el rango (len (data [cur_y_idx])): # Recorrer el eje X de la capa actual 
        lst_tmp.append (data [cur_y_idx] [x_idx]) # Colocar los elementos del eje X de la capa actual Agregue a lst_tmp 
        si cur_y_idx == max_y_idx: # Si la capa actual es la capa inferior, agregue lst_tmp como elemento a lst_rst 
            lst_rst.append ([* lst_tmp])  
        else: # Si la capa actual no es la capa inferior, el eje Y +1 continúa Recursión hacia abajo, por lo que el número máximo de capas de recursión es el valor máximo del eje Y. 
               Las direcciones de lst_rst y lst_tmp también se pasan a la siguiente recursión, de modo que no importa qué capa se modifique, el mismo objeto de lista 
            dynloop_rcsn (data, cur_y_idx + 1, lst_rst, lst_tmp)
        lst_tmp.pop () # Al final de este bucle, independientemente de la recursividad Si regresa, aún necesita eliminar el último elemento de 

    lst_tmp. El 


" 
método de bucle " lst_rst multiplicará 
el bucle de múltiples capas en un bucle de una sola capa, es decir, el eje Y tiene solo 0, solo el eje X y 2 dimensiones. La matriz se convierte en una matriz unidimensional. 
La dificultad es que cada ciclo debe calcular el índice de cada elemento extraído para extraer los elementos en la matriz 2D original. 
'' ' 
def dynloop_loop (datos): 
    max_y_idx = len (datos) # Obtenga el valor máximo del eje Y del conjunto 2D original 
    row_max_idx = 1 # Registre el valor máximo del eje X, el valor inicial es 1, el siguiente calculará 
    arr_len, lst_row, lst_rst = [], [], [] 
    arr_idx = [0] * max_y_idx # Guarde el conjunto de valores de índice de los elementos max_y_idx extraídos cada vez, el valor inicial es [0, 0, 0, 0] 

    # Convierta los datos de la matriz bidimensional En una matriz unidimensional lst_row 
    para el elemento en los datos: 
        _n = len (elemento) # encuentre la longitud de cada capa en la matriz bidimensional original 
        arr_len.append (_n) # guarde la colección de la longitud de cada capa en la matriz bidimensional original
        lst_row + = item # Agregue cada elemento de la matriz bidimensional original a la matriz unidimensional lst_row 
        row_max_idx * = _n # Registre el número total de bucles necesarios 
    para la 

    matriz unidimensional # Atraviese la matriz unidimensional para row_idx en el rango (row_max_idx): 
        # Encuentre cada El valor de índice de los elementos extraídos 
        para y_idx en el rango (max_y_idx): 
            # Recorre el conjunto de 'cortes' de la longitud de cada capa de la matriz 2D original, por ejemplo: lst = [1, 2, 3, 4] 
            # Entonces lst [2: ] Es [3, 4], es decir, a partir del subíndice 2; lst [: 2] es [1, 2], que está antes del subíndice 2. 
            # _pdt es la abreviatura del producto, que registra la matriz bidimensional actual El producto de las longitudes de todas las capas debajo de la capa 
            _pdt = 1 
                _offset + = n
            para n en arr_len [y_idx + 1:]: 
                _pdt * = n 
            # _offset es el desplazamiento, registre la suma de las longitudes de todas las capas por encima de la capa actual de la matriz 2D original 
            _offset = 0 
            para n en arr_len [: y_idx]: 
Relativamente hablando, el método recursivo es más fácil de leer el código, y está más en línea con la intuición del pensamiento; el método de bucle es más eludido pero no hay relativamente restricciones en el número de capas recursivas. 
Los siguientes son los dos métodos para la misma prueba de datos, puede ver que las dos listas devueltas tienen el mismo elemento.
            # Calcule el índice de extracción del elemento: divida el valor actual del eje X por _pdt, y luego tome el resto de la longitud de la capa actual de la matriz 2D original, y finalmente agregue el desplazamiento 
            arr_idx [y_idx] = (row_idx // _pdt)% arr_len [y_idx] + _offset 

        # Recorre la colección de índice, seleccione elementos de la matriz unidimensional y colóquelos en 
        _lst_tmp_lst_tmp = [] 
        para idx en arr_idx: 
            _lst_tmp.append (lst_row [idx]) 
        # Finalmente agregue _lst_tmp como elemento para lst_rst 
        lst_rst .append (_lst_tmp) 

    return lst_rst 



'' '
'' ' 
if __name__ == "__main__": 

    data = [ 
        [1, 2], 
        [3, 4, 5], 
        [6, 7, 8, 9] 
    ] 

    print (' --------- ------- ') 
    lst1 = dynloop_loop (datos) 
    print (len (lst1)) 
    print (lst1)

    print ('----------------') 
    lst2 = dynloop_rcsn (datos) 
    print (len (lst2)) 
    print (lst2) 

    print ('--------- ------- ') 
    # Si dos listas tienen el mismo elemento, devuelve True 
    print (lst1 == lst2)

 

import itertools 
from dynloop_loop_rcsn import dynloop_loop, dynloop_rcsn 


if __name__ == "__main__": 

    data = [ 
        [1, 2], 
        [3, 4, 5], 
        [6, 7, 8, 9], 
        [11, 12], 
        [ 11, 12], [ 13, 14, 15], 
        [16, 17, 18, 19], 
        [21, 22], 
        [23, 24, 25], 
        [26, 27, 28, 29] 
    ] 

    imprimir ('------ ---------- ') 
    lst1 = dynloop_loop (datos) 
    print (len (lst1)) 
    #print (lst1) 

    print (' ---------------- ' ) 
    lst2 = dynloop_rcsn (datos) 
    print (len (lst2)) 
    #print (lst2) 

    print ('----------------') 
    lst3 = list (map (list, (itertools.product (* data))))
    print (len (lst3)) 
    #print (lst3) 

    print ('----------------') 
    print (lst1 == lst2, lst2 == lst3)

 

/ Users / abc / PycharmProjects / testpy / venv / bin / python /Users/abc/PycharmProjects/testpy/test.py

----------------

13824

----------------

13824

----------------

13824

----------------

Verdad verdad

 

Proceso terminado con el código de salida 0

27 artículos originales publicados · elogiados 4 · visitas 9693

Supongo que te gusta

Origin blog.csdn.net/yoshubom/article/details/104124333
Recomendado
Clasificación