'' ' Les boucles dynamiques sont deux implémentations Python3 d'un nombre indéfini de boucles (récursives, boucle pure) # Remarque: Python n'a qu'un type de liste par défaut, et il peut être compris comme un tableau de C. # Pour prendre 3 éléments des 3 tableaux suivants pour en former un, et imprimer les données de combinaisons possibles = [ [1, 2], [3, 4, 5], [6, 7, 8, 9] ] # Cela signifie qu'il y aura 2 * 3 * 4 = 24 possibilités, c'est-à-dire le produit Deca de toutes les listes. La solution peut être réalisée avec une triple boucle. Par exemple: pour i dans les données [0]: pour j dans les données [1]: pour k dans data [2]: print ([i, j, k]) Mais si le nombre de tableaux dans les données est incertain, que se passe-t-il si nous implémentons une boucle de couche dynamique indéfinie? Je pense aux données comme un tableau à deux dimensions: la première dimension est le nombre de données contenant le tableau, c'est-à-dire l'axe Y, en commençant par 0 et augmentant de haut en bas; la deuxième dimension est le nombre d'éléments contenus dans chaque tableau, c'est-à-dire l'axe X , À partir de 0 et en augmentant colonne par colonne de gauche à droite, puis traiter les deux axes X et Y avec des méthodes de boucle récursive et pure respectivement. '' ' ' '' Méthode récursive Depuis la première couche de l'axe Y, c'est-à-dire index = 0, récursivement de haut en bas. Lorsque la couche inférieure est atteinte, une boucle est utilisée pour ajouter un élément de la couche inférieure à la liste à renvoyer à chaque fois. Remarque: Python a une limite sur le nombre de couches récursives, et différents systèmes d'exploitation ont des limites différentes. Il est nécessaire d'envisager un autre algorithme lorsqu'il est supérieur à 100 couches. '' ' # source de données, cur_y_idx valeur actuelle de l'axe Y, lst_rst renvoie la liste des résultats, lst_tmp est utilisé pour assembler temporairement des éléments de lst_rst def dynloop_rcsn (data, cur_y_idx = 0, lst_rst = [], lst_tmp = []): max_y_idx = len (data) -1 # Récupère la valeur d'index maximale de l'axe Y pour x_idx dans la plage (len (data [cur_y_idx])): # Traverse l'axe X du calque courant lst_tmp.append (data [cur_y_idx] [x_idx]) # Met les éléments de l'axe X du calque courant Ajouter à lst_tmp si cur_y_idx == max_y_idx: # Si la couche actuelle est la couche inférieure, ajouter lst_tmp comme élément à lst_rst lst_rst.append ([* lst_tmp]) else: # Si la couche actuelle n'est pas la couche inférieure, l'axe Y +1 continuer Récursion vers le bas, donc le nombre maximal de couches de récursivité est la valeur maximale de l'axe Y. Les adresses de lst_rst et lst_tmp sont également transmises à la récursivité suivante, de sorte que, quelle que soit la couche modifiée, le même objet de liste dynloop_rcsn (data, cur_y_idx + 1, lst_rst, lst_tmp) lst_tmp.pop () # À la fin de cette boucle, quelle que soit la récursivité Si vous revenez, vous devez toujours supprimer le dernier élément de lst_tmp. La lst_rst '' ' méthode de boucle ' multipliera la boucle multicouche en une boucle à couche unique, c'est-à-dire que l'axe Y n'a que 0, uniquement l'axe X et 2 dimensions. Le tableau devient un tableau à 1 dimension. La difficulté est que chaque boucle doit calculer l'index de chaque élément extrait pour extraire les éléments du tableau 2D d'origine. '' ' def dynloop_loop (données): max_y_idx = len (data) # Obtenez la valeur maximale de l'axe Y du tableau 2D d'origine row_max_idx = 1 # Enregistrez la valeur maximale de l'axe X, la valeur initiale est 1, ce qui suit calculera arr_len, lst_row, lst_rst = [], [], [] arr_idx = [0] * max_y_idx # Enregistrer l'ensemble des valeurs d'index des éléments max_y_idx extraits à chaque fois, la valeur initiale est [0, 0, 0, 0] # Convertir les données du tableau à 2 dimensions Dans un tableau unidimensionnel lst_row pour l'élément dans les données: _n = len (item) # recherchez la longueur de chaque couche dans le tableau bidimensionnel d'origine arr_len.append (_n) # enregistrez la collection de la longueur de chaque couche dans le tableau bidimensionnel d'origine lst_row + = item # Ajouter chaque élément du tableau à 2 dimensions d'origine au tableau à 1 dimension lst_row row_max_idx * = _n # Enregistrez le nombre total de boucles nécessaires pour le tableau à 1 dimension # Parcourez le tableau à 1 dimension pour row_idx dans la plage (row_max_idx): # Trouvez chacun La valeur d'index des éléments extraits pour y_idx dans la plage (max_y_idx): # Parcourez l'ensemble des «tranches» de la longueur de chaque couche du tableau 2D d'origine, par exemple: lst = [1, 2, 3, 4] # Then lst [2: ] Est [3, 4], c'est-à-dire à partir de l'indice 2; lst [: 2] est [1, 2], qui est avant l'indice 2. # _pdt est l'abréviation de produit, qui enregistre le tableau bidimensionnel actuel Le produit des longueurs de tous les calques sous le calque _pdt = 1 _offset + = n pour n dans arr_len [y_idx + 1:]: _pdt * = n # _offset est le décalage, enregistrez la somme des longueurs de toutes les couches au-dessus de la couche actuelle du tableau 2D d'origine _offset = 0 pour n dans arr_len [: y_idx]: # calcul Index d'extraction des éléments: la valeur actuelle de l'axe X est divisée par _pdt, puis le reste de la longueur de couche actuelle du tableau 2D d'origine est ajouté, et enfin le décalage arr_idx [y_idx] = (row_idx // _pdt)% arr_len [y_idx] + _offset # Parcourez la collection d'index, sélectionnez les éléments du tableau unidimensionnel et placez-les dans _lst_tmp_lst_tmp = [] pour idx dans arr_idx: _lst_tmp.append (lst_row [idx]) # Enfin, ajoutez _lst_tmp comme élément à lst_rst.append (_lst_tmp) return lst_rst '' ' Relativement parlant, la méthode récursive est plus facile à lire le code, et elle est plus conforme à l'intuition de penser; la méthode de boucle est plus contournée mais il n'y a pas de limite au nombre de couches récursives. Voici les deux méthodes pour le même test de données, vous pouvez voir que les deux listes renvoyées ont le même élément. '' ' si __name__ == "__main__": data = [ [1, 2], [3, 4, 5], [6, 7, 8, 9] ] print (' --------- ------- ') lst1 = dynloop_loop (data) print (len (lst1)) print (lst1) print ('----------------') lst2 = dynloop_rcsn (data) print (len (lst2)) print (lst2) print ('--------- ------- ') # Si deux listes ont le même élément, retourne True print (lst1 == lst2)
importez itertools depuis dynloop_loop_rcsn importez dynloop_loop, dynloop_rcsn si __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] ] print ('------ ---------- ') lst1 = dynloop_loop (data) print (len (lst1)) #print (lst1) print (' ---------------- ' ) lst2 = dynloop_rcsn (data) 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
----------------
Vrai vrai
Processus terminé avec le code de sortie 0