En ce qui concerne python, quand il s'agit d'une boucle for, va-t-il réévaluer la limite supérieure avant la réitération?
Disons que j'ai le scénario suivant:
def remove(self,list,element):
for x in range(0,len(list)):
if somecondition:
list.pop(x)
3 Réponses :
Oui, vous pouvez voir une erreur hors limites si vous essayez ce qui suit:
my_list = [0,1,2,3,4,5]
for x in range(0, len(my_list)):
print("Length of my_list:", len(my_list))
my_list.pop(x)
(Vous devriez également éviter d'utiliser un nom de variable comme list car il suivra la list intégrée de Python.)
Il s'agissait plus d'un exemple générique que d'un code réel.
À quoi dites-vous «oui»? La réponse à la question dans le titre est clairement "Non". Cela ne démontre pas que range () est réévalué à chaque itération - bien au contraire (car ce n'est pas le cas). Au lieu de cela, lorsque x devient 3, il ne reste plus que 3 éléments dans ma_liste donc le pop est hors de portée. L'itération est fixée à 6, l'itération se termine par l'erreur, non par la réévaluation de la longueur. Il faut éviter de répondre «oui» ou «non» - la question pourrait facilement être modifiée pour inverser le sens. Il est plus sûr de déclarer clairement ce que vous affirmez.
La documentation sur La déclaration for est claire à propos de ceci:
L'instruction for est utilisée pour parcourir les éléments d'une séquence (comme une chaîne, un tuple ou une liste) ou autre objet itérable:
for_stmt :: = "pour" target_list "dans" expression_list ":" suite ["else" ":" suite]
La liste d'expressions est évaluée une fois ; il doit produire un objet itérable. Un itérateur est créé pour le résultat de l'expression_list. La suite est ensuite exécutée une fois pour chaque élément fourni par l'itérateur, dans l'ordre renvoyé par le itérateur.
[c'est moi qui souligne]
Donc, dans votre cas, range (0, len (list)) ne sera évalué qu'une seule fois.
Je vois, ai-je raison de supposer que cela serait également vrai pour la plage (0, Y)? Étant donné que Y est modifié à l'intérieur de la boucle
Vous l'êtes, ce serait le cas pour n'importe quelle expression. L'objet range est créé une fois pour toutes, puis il sera itéré dessus.
Considérez le code suivant:
0 4 1 4 2 4 3 4
Chaque fois que test () est appelé i est incrémenté, la boucle sera donc sans fin si code > test () `ont été évalués à chaque itération. Le résultat est cependant:
i = 3 def test(): global i ; i = i + 1 return i for x in range(0,test()): print( x, i )
Il est donc clair que test () est évalué une fois.
Une vérification rapide suggère que
len (some_list)ne sera pas réévalué si vous ajoutez pendant l'itération. OTOH, si vous bouclez sur la liste elle-même et ajoutez (for x in some_list:) alors l'itérateur devient confus. La mutation des collections tout en les itérant est généralement évitée en Python, à moins que vous ne sachiez ce que vous faites.Quelle enquête avez-vous essayée - c'est assez facile à démontrer.
Vous devriez lire sur les générateurs en python. La boucle for est juste un wrapper pour try, iter = next (gen) do loop, catch. Cela permet une compréhension plus profonde