簡體   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