在python中使用相同项循环迭代的任何方法?

时间:2009-04-01 14:36:47

标签: python iterator

循环迭代而不接收下一个项目是一个常见的编程任务。例如:

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 个答案:

答案 0 :(得分:3)

我首先想到你想要continue关键字,但这当然会让你获得下一行输入。

我觉得我很难过。当循环遍历文件的行时,如果继续循环而没有获得新行,究竟应该发生什么?

您想再次检查线路吗?如果是这样,我建议添加一个内部循环,直到你用输入行“完成”,然后你可以break出来,或者使用while - 条件和一个标志变量终止。

答案 1 :(得分:2)

只需创建一个自己的迭代器,就可以将数据推回到流的前面,这样就可以为循环提供一条想要再次查看的行:

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上,那么在它返回到主迭代器的读取之前,它们将首先被放置。

答案 2 :(得分:1)

您需要的是一个简单的,确定性的finite state machine。像这样......

state = 1
for sLine in oFile:
   if state == 1:
      if ... some logic ... :
         state = 2
   elif state == 2:
      if ... some logic ... :
         state = 1

答案 3 :(得分:0)

您可以将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]即可转到上一行或下一行。你只需要确保无论如何,我都不会超出范围。

答案 4 :(得分:0)

难看。将身体包裹在另一个循环中。

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 ...

不幸的是没有简单的方法来引用当前的迭代器。

答案 5 :(得分:-1)

您可以将迭代器分配给变量,然后使用.next get te next。

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

答案 6 :(得分:-1)

您只需要从迭代器中创建一个变量,然后操作它:

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

import sys

lines = iter(open(sys.argv[1]))
for line in lines:
    print line,
    lines.next()

% cat /tmp/test
1
2
3
4
% /tmp/alt-lines.py /tmp/test
1
3

...请注意,在这种情况下,我们无条件地执行lines.next(),因此上面的奇数行文件失败,但我认为不会是你的情况(并添加错误检查是相当简单 - 只需在手册.next()上捕获并丢弃StopIteration。

答案 7 :(得分:-2)

jle的方法应该可行,但你也可以使用enumerate():

for linenr, line in enumerate(oFile):
    # your stuff