Ich denke, ** multiple for loop (Verschachtelung) ** ist einer der vermeidbarsten Prozesse in der Programmierung. Vor ungefähr einem Monat wurde der Artikel "Warum vermeiden wir hartnäckig für" und 2020/11/3 Mit mehr als 1000 LGTMs möchten viele Menschen nicht zu viel für Schleifen verwenden. In Python gibt es verschiedene Techniken, mit denen mehrere for-Schleifen leicht vermieden werden können. Daher habe ich die Techniken zusammengefasst, die ich am häufigsten verwende. Wenn Sie andere haben, teilen Sie uns dies bitte in den Kommentaren mit.
Ich denke, dass jede Person verschiedene Gründe hat (der obige Artikel behandelt auch verschiedene Details), aber persönlich gibt es die folgenden zwei Punkte.
Als Beispiel für mehrere for-Schleifen schreiben wir ein Programm, das alle 0 bis 999 durchsucht, indem eine for-Anweisung in jeder der drei Ziffern von 0 auf 9 gesetzt wird, und nach einer Zahl sucht, die 500 oder mehr beträgt und ein zor ist. (geeignet) Schon eine Triple-for-Schleife bringt Sie zum Lachen.
schlechtes Beispiel
result = []
for i in range(10):
for j in range(10):
for k in range(10):
summed = i*100+j*10+k
if i == j == k and summed >= 500:
result.append(summed)
print(result)
#Ausführungsergebnis-> [555, 666, 777, 888, 999]
Es ist immer noch gut, weil der Prozess einfach ist, aber es wird sehr schwer zu lesen, wenn es komplizierter wird.
Oft möchten Sie alle Schleifen verlassen, nicht nur die innerste, wenn Sie bestimmte Bedingungen erfüllen. Schreiben Sie als Beispiel ein Programm, das den Prozess beendet, wenn es im Prozess von 1. oben sogar ein Zoro-Auge findet. Wenn ich bei Google nach "Wie man aus mehreren Python-Schleifen herauskommt" suche, wird es wie folgt geschrieben, obwohl es einen Unterschied gibt, z. B. wenn kein Flag verwendet wird.
Es gibt eine schlechte Beispielpause
result = []
for i in range(10):
for j in range(10):
for k in range(10):
summed = i*100 + j*10 + k
if i == j == k and summed >= 500:
result.append(summed)
break
else:
continue
break
else:
continue
break
print(result)
#Ausführungsergebnis-> [555]
Das ist ziemlich schwer zu lesen. Es ist sehr schwer zu sagen, wo und wo der Einzug gleich ist. Wenn Sie versuchen, kompliziertere Prozesse zu schreiben, erhalten Sie Code, den niemand verstehen kann.
Mithilfe von itertools können Sie Iteratoren generieren, die alle Kombinationen erzeugen und mehrere for-Schleifen vermeiden. Da es sich um einen Iterator handelt, der generiert wird, verbraucht er nicht viel Speicher, selbst wenn Sie alle Kombinationen vornehmen. Wenn Sie alle von Ihnen erstellten Kombinationen auflisten möchten, fügen Sie einfach den Iterator hinzu, der von der integrierten Funktionsliste () erstellt wurde. (Achten Sie beim Auflisten auf den Speicherverbrauch.)
Wenn ich den Code, der aus der vorherigen Schleife ausbricht, mit itertools schreibe,
Bei Verwendung von itertools
import itertools
all_nums_iter = itertools.product(range(10),repeat=3)
result = []
for num in all_nums_iter:
summed = num[0]*100 + num[1]*10 + num[2]
if num[0] == num[1] and num[1] == num[2] and summed >= 500:
result.append(summed)
break
print(result)
#Ausführungsergebnis-> [555]
Ich denke es ist leichter zu sehen. Itertools verfügt übrigens über eine Funktion, mit der nicht nur alle, sondern auch Kombinationen und Sequenzen mit oder ohne Duplizierung aufgelistet werden können.
Wenn Sie bereits ein numpy-Array verwenden, können Sie numpy.npindex verwenden, um mehrere for-Schleifen zu vermeiden. numpy.npindex dreht die for-Anweisung so, dass alle Werte im empfangenen Array gerundet werden. Im folgenden Code lautet options.shape (10, 10, 10), sodass i, j und k vollständig nach Anweisungen von 0 bis 9 suchen.
numpy.Bei Verwendung von npindex
import numpy as np
options = np.array([[[100*i+10*j+k for i in range(10)] for j in range(10)] for k in range(10)], dtype="int")
result = []
for i, j, k in np.ndindex(options.shape):
summed = options[i,j,k]
if i == j and j == k and summed >= 500:
result.append(summed)
break
print(result)
#Ausführungsergebnis-> [555]
Es ist ziemlich erfrischend.
Es ist ein wenig schwierig und ich denke, es wird in einer begrenzten Anzahl von Situationen verwendet, aber Sie können auch eine vollständige Suche mit einer rekursiven Funktion durchführen. Wenn Sie mit rekursiven Funktionen nicht vertraut sind, lesen Sie bitte "Welche Art von Welt wird sich erweitern, wenn Sie rekursive Funktionen lernen" in der folgenden Referenz. Ich denke, es ist ziemlich leicht zu verstehen.
Bei Verwendung einer rekursiven Funktion
def dfs(depth, num):
if depth == 3:
num_str = str(num).zfill(3)
return num if num_str[0] == num_str[1] == num_str[2] and num >= 500 else None
for i in range(10):
ret = dfs(depth + 1, num + 10**(2-depth) * i)
if ret:
return ret
print(dfs(0, 0))
#Ausführungsergebnis-> 555
Sie können es in einer begrenzten Anzahl von Situationen verwenden, aber Sie können in bestimmten Situationen intuitiven Code schreiben (DFS: Suche nach Tiefenprioritäten usw.).
Warum vermeiden wir es hartnäckig für Häufig verwendete Methode in der Python-Version von atcoder Welche Art von Welt wird sich erweitern, wenn Sie rekursive Funktionen lernen
Vielen Dank für das Lesen bis zum Ende. Vereinfachen wir das schwer lesbare Multiple für Schleifen. Wenn Sie eine andere einfache Möglichkeit zum Schreiben kennen, lassen Sie es mich bitte in den Kommentaren wissen. Wenn Sie diesen Artikel hilfreich finden, verwenden Sie bitte LGTM!
Recommended Posts