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

jr0*_*r0d 48 python iterator

我可能以错误的方式解决这个问题,但我想知道如何在python中处理这个问题.

首先是一些c代码:

int i;

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

好的,所以我们永远不会看到50年代......

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

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

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

必须有一个更好的方法来做到这一点,希望是一个不涉及导入另一个模块的方法.

提前致谢!

Fil*_*vić 44

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
Run Code Online (Sandbox Code Playgroud)

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

在底部,您可以找到Recipes部分,其中包含使用现有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)
Run Code Online (Sandbox Code Playgroud)

这是一个快速,可读的示例,说明它是如何工作的(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
Run Code Online (Sandbox Code Playgroud)

  • 请注意,与原始代码不同,这是迭代的.如果你使用一个巨大的范围,你可以看到差异,例如.xrange(1000000000),做很大的跳跃.通常这没关系,但在一些算法中它可能(例如,如果生成项目很昂贵),所以要注意它.没有API要求迭代器跳过项目; 它必须迭代运行它. (5认同)
  • 你可能想要使用`iterator = iter(range(1,16))`而不是`__iter__`.(偏离主题的说明:`xrange`可以在这里更好地提供这个特定的代码,但是*学习*迭代器是一个不令人满意的例子.) (2认同)

jfs*_*jfs 17

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
Run Code Online (Sandbox Code Playgroud)

例如,如果exp,cdata是:

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

然后输出是:


before skip
5 after skip
6 

C实例的Python实现

i = 0
while i < 100:
    if i == 50:
       i += 10
    print i
    i += 1
Run Code Online (Sandbox Code Playgroud)

正如@ [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
Run Code Online (Sandbox Code Playgroud)

此示例生成与上islice例相同的输出.