Python для вопроса о петле - PullRequest
25 голосов
/ 12 марта 2010

Мне было интересно, как достичь следующего в python:

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

Я попробовал это без удачи.

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

Ответы [ 7 ]

37 голосов
/ 12 марта 2010

Питон для циклов разные. i переназначается на следующее значение каждый раз через цикл.

Следующее будет делать то, что вы хотите, потому что оно принимает буквальную версию того, что делает C ++:

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

И вот почему:

в C ++ следующие сегменты кода эквивалентны:

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

и

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

тогда как цикл python for выглядит примерно так:

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

превращается в

my_iter = iter(..a..)
while (my_iter is not empty):
    x = my_iter.next()
    ..code..
11 голосов
/ 12 марта 2010

Существует ключевое слово continue, которое пропускает текущую итерацию и переходит к следующей (и ключевое слово break, которое пропускает все итерации цикла и выходит из цикла):

for i in range(10):
    if i % 2 == 0:
      # skip even numbers
      continue 
    print i
4 голосов
/ 12 марта 2010

Вы можете явно увеличить итератор.

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

Вам нужно поймать StopIteration, если cond может быть True на последнем элементе.

4 голосов
/ 12 марта 2010

Помните, что вы перебираете элементы в списке, а не перебираете число.

Например, рассмотрим следующее:

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

Что бы произошло, если бы вы сделали там +1? Теперь вы можете понять, почему он не пропускает следующий элемент в списке.

Вместо того, чтобы фактически итерировать по всем значениям, вы можете попытаться настроить то, что содержится внутри списка, по которому вы перебираете.

Пример:

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

Вы также можете рассмотреть разбиение тела for на 2. Первая часть перейдет к следующему элементу с помощью continue, а вторая часть выполнит действие, если вы не пропустили.

2 голосов
/ 16 марта 2010

Существует альтернативный подход к этому, в зависимости от задачи, которую вы пытаетесь выполнить. Если cond полностью зависит от входных данных, которые вы зацикливаете, вы можете попробовать что-то вроде следующего:

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

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

Это функциональный способ программирования, похожий на LINQ в C # 3.0+. Я не уверен, что все это питонно (какое-то время Гвидо ван Россум хотел убрать фильтр, карту и уменьшение из Python 3), но это, безусловно, элегантно и так, как я бы это сделал.

1 голос
/ 12 марта 2010

Вы не можете тривиально «пропустить следующий этап» (вы, конечно, можете пропустить этот этап с continue). Если вы действительно настаиваете, вы можете сделать это с помощью вспомогательного bool, например

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

или для общности со вспомогательным int:

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

Однако было бы лучше инкапсулировать такую ​​сложную циклическую логику в соответствующий генератор - трудно привести примеры, если только вы не можете быть немного более конкретным относительно того, что вы хотите (хотя это «псевдо-C» с двумя предположительно 100% ДЕЙСТВИТЕЛЬНО трудно следовать различным использованиям одного и того же логического cond; -).

0 голосов
/ 16 марта 2010
for i in filter(lambda x:x!=2,range(5)):
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...