python中的for语句可以在任意序列_python在循环内任意增加迭代器

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

我可能会以错误的方式处理此问题,但我想知道如何在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。

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

提前致谢!

jr0d asked 2020-06-25T22:20:57Z

8个解决方案

44 votes

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

但是在开始之前,它很好地解释了如何在Python中实现迭代协议。 当要在容器上提供迭代时,请指定提供迭代器类型的itertools类方法。 “了解Python的'for'语句”是一篇不错的文章,介绍了293913273348391010144语句在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

Filip Dupanović answered 2020-06-25T22:21:35Z

16 votes

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

例如,如果islice、islice是:

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),则应使用显式islice循环,而不是仅跳过islice循环中的步骤。

这是使用显式islice循环而不是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示例相同的输出。

jfs answered 2020-06-25T22:22:21Z

2 votes

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

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

Benno answered 2020-06-25T22:22:50Z

1 votes

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

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(..))应该可以为您提供帮助。

rh0dium answered 2020-06-25T22:23:15Z

1 votes

您可以从迭代器中删除值

def dropvalues(iterator, vals):

for i in xrange(vals): iterator.next()

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

u0b34a0f6ae answered 2020-06-25T22:23:39Z

0 votes

也许与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生成异常。

mjv answered 2020-06-25T22:24:08Z

0 votes

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

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

fortran answered 2020-06-25T22:24:37Z

-6 votes

我无法解析这个问题,因为这里存在混乱且无关的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

S.Lott answered 2020-06-25T22:25:01Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值