Любой способ зациклить итерацию с тем же элементом в Python? - PullRequest
0 голосов
/ 01 апреля 2009

Это обычная задача программирования, чтобы зациклить итерацию, не получая следующий элемент. Например:

for sLine in oFile :
  if ... some logic ... :
    sLine = oFile.next()
    ... some more logic ...
    # at this point i want to continue iteration but without
    # getting next item from oFile. How can this be done in python?

Ответы [ 8 ]

3 голосов
/ 01 апреля 2009

Сначала я подумал, что вам нужно ключевое слово continue, но это, конечно, даст вам следующую строку ввода.

Я думаю, что я в тупике. Что именно должно произойти при цикле по строкам файла, если вы продолжили цикл, не получив новую строку?

Хотите еще раз проверить линию? Если это так, я предлагаю добавить внутренний цикл, который будет выполняться до тех пор, пока вы не «закончите» со строкой ввода, из которой затем вы можете break выйти или использовать, возможно, while -условие и переменную flag для завершения.

2 голосов
/ 01 апреля 2009

Просто создайте свой собственный итератор, который позволит вам перенести данные обратно в начало потока, чтобы вы могли задать циклу строку, которую вы хотите просмотреть снова:

next_lines = []
def prependIterator(i):
    while True:
        if next_lines:
            yield(next_lines.pop())
        else:
            yield(i.next())

for sLine in prependIterator(oFile):
    if ... some logic ... :
        sLine = oFile.next()
        ... some more logic ...
        # put the line back so that it gets read
        # again as we head back up to the "for
        # statement
        next_lines.append(sLine)

Если prepend_list никогда не трогать, то prependIterator ведет себя точно так же, как и любой итератор, который он пропустил: оператор if внутри всегда получит False и просто выдаст все в итераторе, который он передал. Но если элементы помещаются в prepend_list в любой точке во время итерации, то они будут сначала получены, а не возвращены к чтению из основного итератора.

1 голос
/ 01 апреля 2009

Вам нужен простой, детерминированный конечный автомат . Как то так ...

state = 1
for sLine in oFile:
   if state == 1:
      if ... some logic ... :
         state = 2
   elif state == 2:
      if ... some logic ... :
         state = 1
0 голосов
/ 01 апреля 2009

Вам просто нужно создать переменную из вашего итератора, а затем манипулировать этим:

% cat /tmp/alt-lines.py 
<code>#! /usr/bin/python -tt

import sys

lines = iter(open(sys.argv[1]))
for line in lines:
    print line,
    lines.next()
</code>
% cat /tmp/test
1
2
3
4
% /tmp/alt-lines.py /tmp/test
1
3

... обратите внимание, что в этом случае мы безоговорочно выполняем lines.next (), поэтому вышеописанное не работает для файлов с нечетными строками, но я предполагаю, что это не так (и добавление проверки ошибок довольно тривиально - просто лови и выбрасывай StopIteration по инструкции .next ()).

0 голосов
/ 01 апреля 2009

Вы можете назначить свой итератор переменной, а затем использовать .next get te.

iter = oFile.xreadlines() # is this the correct iterator you want?
try:
  sLine = iter.next()
  while True:
    if ... some logic ... :
      sLine = iter.next()
      ... some more logic ...
      continue
    sLine = iter.next()
except StopIterator:
  pass
0 голосов
/ 01 апреля 2009

Гадкий. Оберните тело в другую петлю.

for sLine in oFile :
  while 1:
    if ... some logic ... :
      sLine = oFile.next()
      ... some more logic ...
      continue
    ... some more logic ...
    break

Чуть лучше:

class pushback_iter(object):
    def __init__(self,iterable):
        self.iterator = iter(iterable)
        self.buffer = []
    def next(self):
        if self.buffer:
            return self.buffer.pop()
        else:
            return self.iterator.next()
    def __iter__(self):
        return self
    def push(self,item):
        self.buffer.append(item)

it_file = pushback_iter(file)
for sLine in it_file:
    if ... some logic ... :
        sLine = it_file.next()
        ... some more logic ...
        it_file.push(sLine)
        continue
    ... some more logic ...

К сожалению, нет простого способа ссылки на текущий итератор.

0 голосов
/ 01 апреля 2009
Подход

jle должен работать, хотя вы также можете использовать enumerate ():

for linenr, line in enumerate(oFile):
    # your stuff
0 голосов
/ 01 апреля 2009

Вместо того, чтобы циклически проходить по файлу, вы можете сделать file.readlines () в списке. Затем переберите список (который позволяет вам посмотреть следующий элемент, если хотите). Пример:

list = oFile.readlines()
for i in range(len(list))
    #your stuff
    list[i] #current line
    list[i-1] #previous line
    list[i+1] #next line

Вы можете перейти к предыдущей или следующей строке, просто используя [i-1] или [i + 1]. Вам просто нужно убедиться, что несмотря ни на что, я не выхожу за пределы диапазона.

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