web-dev-qa-db-fra.com

Python pour la question de boucle

Je me demandais comment réaliser ce qui suit en python:

for( int i = 0; cond...; i++)
  if cond...
    i++; //to skip an run-through

J'ai essayé sans succès.

for i in range(whatever):
  if cond... :
    i += 1
26
Joe Dunk

Les boucles for de Python sont différentes. i est réaffecté à la valeur suivante à chaque fois dans la boucle.

Ce qui suit fera ce que vous voulez, car il prend la version littérale de ce que fait C++:

i = 0
while i < some_value:
    if cond...:
        i+=1
    ...code...
    i+=1

Voici pourquoi:

en C++, les segments de code suivants sont équivalents:

for(..a..; ..b..; ..c..) {
    ...code...
}

et

..a..
while(..b..) {
     ..code..
     ..c..
}

alors que la boucle python for ressemble à quelque chose comme:

for x in ..a..:
    ..code..

se transforme en

my_iter = iter(..a..)
while (my_iter is not empty):
    x = my_iter.next()
    ..code..
40
jakebman

Il existe un mot clé continue qui ignore l'itération en cours et passe à la suivante (et un mot clé break qui ignore toutes les itérations de boucle et quitte la boucle):

for i in range(10):
    if i % 2 == 0:
      # skip even numbers
      continue 
    print i
11
tux21b

Vous pouvez explicitement incrémenter l'itérateur.

whatever = iter(whatever)
for i in whatever:
    if cond:
        whatever.next()

Vous devrez intercepter StopIteration si cond peut être True sur le dernier élément.

4
user97370

N'oubliez pas que vous itérez sur les éléments de la liste et non sur un nombre.

Par exemple, considérez ce qui suit:

for i in ["cat", "dog"]:
  print i

Que se passerait-il si vous faisiez i + 1 là-bas? Vous pouvez voir maintenant pourquoi il ne saute pas l'élément suivant dans la liste.

Au lieu d'itérer réellement sur toutes les valeurs, vous pouvez essayer d'ajuster ce qui est contenu dans la liste que vous parcourez.

Exemple:

r = range(10)
for i in filter(lambda x: x % 2 == 0, r):
  print i

Vous pouvez également envisager de diviser le corps for en 2. La première partie passera à l'élément suivant en utilisant continue, et la deuxième partie fera l'action si vous n'avez pas sauté.

4
Brian R. Bondy

Il existe une approche alternative à cela, selon la tâche que vous essayez d'accomplir. Si cond est entièrement fonction des données d'entrée sur lesquelles vous effectuez une boucle, vous pouvez essayer quelque chose comme ceci:

def check_cond(item):
    if item satisfies cond:
        return True
    return False

for item in filter(check_cond, list):
    ...

C'est la manière de programmation fonctionnelle pour ce faire, un peu comme LINQ en C # 3.0+. Je ne suis pas certain que c'est tout ce que Pythonic (pendant un certain temps, Guido van Rossum a voulu supprimer le filtre, la carte et réduire de Python 3) mais c'est certainement élégant et la façon dont je le ferais .

2
Clueless

Vous ne pouvez pas trivialement "sauter l'étape suivante" (vous pouvez bien sûr sauter cette étape avec un continue). Si vous insistez vraiment, vous pouvez le faire avec un auxiliaire bool, par ex.

skipping = False
for i in whatever:
  if skipping:
    skipping = False
    continue
  skipping = cond
  ...

ou pour la généralité avec un auxiliaire int:

skipping = 0
for i in whatever:
  if skipping:
    skipping -= 1
    continue
  if badcond:
    skipping = 5  # skip 5 legs
  ...

Cependant, il serait préférable d'encapsuler une telle logique de boucle complexe dans un générateur approprié - difficile de donner des exemples, sauf si vous pouvez être un peu plus concret sur ce que vous voulez (ce "pseudo-C" avec deux utilisations probablement 100% différentes de le même booléen cond est VRAIMENT difficile à suivre ;-).

1
Alex Martelli
for i in filter(lambda x:x!=2,range(5)):
0
Luka Rahne