繁体   English   中英

python在循环内任意增加迭代器

[英]python arbitrarily incrementing an iterator inside a loop

我可能会以错误的方式处理此问题,但我想知道如何在python中处理此问题。

首先一些C代码:

int i;

for(i=0;i<100;i++){
  if(i == 50)
    i = i + 10;
  printf("%i\n", i);
}

好吧,我们永远不会看到50年代...

我的问题是,如何在python中做类似的事情? 例如:

for line in cdata.split('\n'):
  if exp.match(line):
    #increment the position of the iterator by 5?
    pass
  print line

由于我在python方面的有限经验,我只有一个解决方案,一个计数器和另一个if语句。 中断循环,直到exp.match(line)为true后计数器达到5。

必须有一种更好的方法来执行此操作,希望它不涉及导入另一个模块。

提前致谢!

Python中有一个很棒的软件包,称为itertools

但是在开始之前,它很好地解释了如何在Python中实现迭代协议。 如果要在容器上提供迭代,请指定提供迭代器类型__iter__()类方法。 “了解Python的'for'语句”是一篇不错的文章,介绍了for-in语句在Python中的实际工作方式,并很好地概述了迭代器类型的工作方式。

看一下以下内容:

>>> sequence = [1, 2, 3, 4, 5]
>>> iterator = sequence.__iter__()
>>> iterator.next()
1
>>> iterator.next()
2
>>> for number in iterator:
    print number 
3
4
5

现在回到itertools 该软件包包含用于各种迭代目的的函数。 如果您需要进行特殊测序,这是第一个研究的地方。

在底部,您可以找到“ 食谱”部分,其中包含使用现有itertools作为构建块来创建扩展工具集的食谱

有一个有趣的功能可以完全满足您的需求:

def consume(iterator, n):
    '''Advance the iterator n-steps ahead. If n is none, consume entirely.'''
    collections.deque(itertools.islice(iterator, n), maxlen=0)

这是一个简单易懂的示例,说明其工作方式(Python 2.5)

>>> import itertools, collections
>>> def consume(iterator, n):
    collections.deque(itertools.islice(iterator, n))
>>> iterator = range(1, 16).__iter__()
>>> for number in iterator:
    if (number == 5):
        # Disregard 6, 7, 8, 9 (5 doesn't get printed just as well)
        consume(iterator, 4)
    else:
        print number

1
2
3
4
10
11
12
13
14
15

itertools.islice

lines = iter(cdata.splitlines())
for line in lines:
    if exp.match(line):
       #increment the position of the iterator by 5
       for _ in itertools.islice(lines, 4):
           pass
       continue # skip 1+4 lines
    print line

例如,如果expcdata为:

exp = re.compile(r"skip5")
cdata = """
before skip
skip5
1 never see it
2 ditto
3 ..
4 ..
5 after skip
6 
"""

然后输出是:

before skip
5 after skip
6

C示例的Python实现

i = 0
while i < 100:
    if i == 50:
       i += 10
    print i
    i += 1

正如@ [Glenn Maynard]在评论中指出的,如果您需要执行非常大的跳转(例如i + = 100000000),则应该使用显式的while循环,而不是仅跳过for循环中的步骤。

这是使用显式while循环而不是islice

lines = cdata.splitlines()
i = 0
while i < len(lines):
    if exp.match(lines[i]):
       #increment the position of the iterator by 5
       i += 5
    else:
       print lines[i]
       i += 1

本示例产生与上述islice示例相同的输出。

如果您使用数字来做,列表理解可以工作:

for i in [x for x in range(0, 99) if x < 50 and x > 59]:
    print i

但是,向前移动迭代器要困难一些。 如果您不想执行计数器方法,建议您先设置列表,方法可能是拆分cdata,然后计算出匹配行的索引,然后删除该行和随后的行。 除此之外,您还受制于反制,这并不是说实话的那样令人不快。

另一个选择是:

iterator = iter(cdata.split('\n'))
for line in iterator:
    if exp.match(line):
        for i in range(0, 5):
            try:
                iterator.next()
            except StopIteration:
                break
    else:
        print line

不完全确定我会遵循您的思考过程,但是有一些需要注意的地方。

for i in range(len(cdata.split('\n'))):
  if i in range(50,60): continue
  line = cdata[i]
  if exp.match(line):
    #increment the position of the iterator by 5?
    pass
  print line

不确定您真正追求的是什么,但是range(len(..))应该可以为您提供帮助。

您可以从迭代器中删除值

def dropvalues(iterator, vals):
    for i in xrange(vals): iterator.next()

现在,只需确保您有一个迭代器对象可以使用lines = iter(cdata.split('\\n')) ; 并遍历它。

也许与genexps。 不漂亮但是...

像这样:

>>> gx = (line for line in '1 2 x 3 4 5 6 7 x 9 10 11 12 x 1'.split('\n'))
>>> for line in gx:
...   if line == 'x':
...      for i in range(2):
...          line = gx.next()
...   print line

唯一的问题是确保gx可以被next()编辑。 上面的示例故意由于最后一个x生成异常。

对于您的示例,由于您正在使用列表(可索引序列)而不是迭代器,因此我建议以下内容:

lines = cdata.split("\n")
for line in lines[:50]+lines[60:]:
  print line

这不是最有效的方法,因为它可能会构造3个新列表(但是如果跳过的部分大于处理的部分,则它可能比其他选项更有效),但是它非常干净明确。

如果您不介意使用itertools模块,则可以轻松地将列表转换为序列:

from itertools import chain, islice
for line in chain(islice(lines, None, 50), islice(lines, 60,None)):
  print line

我无法解析这个问题,因为存在混乱和不相关的C代码块。 请删除它。

仅关注Python代码和有关如何跳过5行的问题...

lineIter= iter( cdata.splitlines() )
for line in lineIter:
  if exp.match(line):
    for count in range(5):
        line = lineIter.next()
  print line

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM