Повторять снова в цикле for - PullRequest
2 голосов
/ 27 января 2011

Есть ли способ повторить снова в цикле for?Например:

for x in list:
  if(condition):
      #I'd like to grab the next iteration of the list 

Так что, если бы у меня было [1,2,3,4], я бы сначала перебрал 1, а затем пытался продвинуть итерацию до 2 внутри цикла for, чтобы прицикл начался снова, он был бы в 3.

Возможно?

Я создаю парсер, который читает оператор if, затем хочет читать строки до тех пор, пока не достигнет строки, котораязавершает оператор if.

Ответы [ 7 ]

3 голосов
/ 27 января 2011

Если элемент, который вы используете, является итеративным объектом, вы можете использовать item.next(), чтобы получить следующий элемент. Но вам нужно убедиться, что вы получили исключение StopIteration, если это необходимо.

>>> it = iter(range(5))
>>> for x in it:
...     print x
...     if x > 3:
...         print it.next()
... 
0 1 2 3 4
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
StopIteration
3 голосов
/ 27 января 2011

Вы можете сделать что-то вроде этого:

a = [1,2,3,4,5]
b = iter(a)

try:
    while True:
        c = b.next()
        if (condition):
            c = b.next()
except StopIteration:
    pass
1 голос
/ 27 января 2011

Вы всегда можете обойти цикл for и просто использовать итератор явно:

iter = list.__iter__()
while True:
    x = iter.next()
    ...
    if (condition):
        x = iter.next()
    ...

Это вызовет исключение StopIteration, когда оно достигнет конца списка.

1 голос
/ 27 января 2011

Вы можете использовать цикл while вместо for.В псевдокоде:

idx = 0
while idx < length(list)
    x = list[idx]
    ...
    if (condition)
        idx += 1
    ...
    idx += 1
1 голос
/ 27 января 2011
skip = False
for x in list:
    if skip:
        skip = False
        continue
    # Do your main loop logic here
    if (condition):
        skip = True
1 голос
/ 27 января 2011

Требуется оператор continue .

for x in list:
  if(condition):
      continue
0 голосов
/ 27 января 2011

Я подозреваю, что ваш подход к синтаксическому анализу оператора if не является хорошим способом для этого. Вы также обнаружите, что не можете вкладывать свои утверждения IF или ставить их все в одну строку. Вот как я бы это сделал.

а) Преобразуйте ваш язык в форму BNF. Например, для оценки if это может быть

ifstmnt ::=  IF &lt;condiftion> THEN &lt;trueblock> [ ELSE &lt;elseblock> ]

statment ::= ifstmnt | assignstment | whilestmnt | forstmnt 

и т.д.

б) Выясните, что вы ждете в каждой точке. После IF вы читаете условие, пока не увидите THEN.

в) Напишите подпрограмму getNextToken, которая читает символы из вашего источника, пока у него не будет полный токен. Токен - это узнаваемая единица - ЕСЛИ, ТО, А, число, символ. Каждый раз, когда он вызывается, он возвращает токен в буфер. Также полезно иметь тип и возвращаемое значение - это сэкономит вам преобразование чисел во многих местах. Настольный подход очень быстрый и гибкий.

d) Затем напишите много маленьких подпрограмм, чтобы распознать каждый тип утверждения. Один для IF, один для условия, один для блока, один для оператора, один для выражения и т. Д. Они будут вызывать друг друга и возвращаться, когда они распознают оператор. Например, распознаватель выражений условия будет читать логическое выражение и принимать все имена, AND, OR и т. Д., Пока не заглянет в будущее и не увидит THEN. Он не может обработать THEN, поэтому он существует, и программа повторного распознавания IF обнаруживает, что токен THEN, читает следующее и вызывает распознаватель для блока (который может ожидать BEGIN, много статистики и затем END).

e) Каждая подпрограмма собирает необходимые данные - условие, истинный блок, ложный блок и обрабатывает их по мере необходимости. Очень распространенным методом является создание древовидного представления программы в памяти. Определенные программистом имена собираются в словаре по мере их определения и проверяются по мере их использования.

f) Затем реальный компилятор попытается изменить расположение дерева, чтобы сделать его более эффективным - но я полагаю, что это будущее развитие

ж) Последнее действие - пройтись по дереву, оценивая его каким-то образом. Если вы пишете интерпретатор, вы можете вычислять значения и сохранять их по ходу дела - сохранять значения в доктрине. Если вы пишете настоящий компилятор, вам нужно сгенерировать подходящий вывод для компоновщика. Это главная задача.

Проверьте YACC и LEX. Это инструменты, предназначенные для выполнения части работы, и сэкономят ваше время. Термины, которые помогут вашему исследованию: «лексический анализ», «анализатор» и тому подобное.

И удачи. Ваш проект нетривиален!

См. Также http://nedbatchelder.com/text/python-parsers.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...