2013-07-24 17 views
16

için aralıklar ile genellikle döngü birkaç tekrarlamadan atlamak ama şimdi döngüde birkaç adım atlamak istiyoruz nasıl. Daha spesifik olarak, continue(10) gibi bir şey istiyorum, böylece tüm döngüyü atlayıp sayacı 10 artırırdım. C için bir döngü kullansaydım, sadece 10 ile i derdim, ama Python'da gerçekten işe yaramaz .Sadece</p> <p>tarafından python'da döngü

cevap

16

for döngüsünün hedef listesini (bu durumda i) değiştiremezsiniz. Alternatif olarak,

while i < 10: 
    i += 1 
    if i == 2: 
     i += 3 

bir iterable kullanımı ve artırmak: yerine while döngü kullanarak yerel bir değişkene iter() sonucunu atayarak

from itertools import islice 

numbers = iter(range(10)) 
for i in numbers: 
    if i == 2: 
     next(islice(numbers, 3, 3), None) # consume 3 

, kullandığımız döngü içinde döngü sekansı ilerlemeden standart iterasyon araçları (next(), veya burada itertools tarifinin kısaltılmış bir versiyonu). for normalde bir yineleyici üzerinde döngü yaparken bizim için iter()'u çağırır.

+4

Ben, bu durumda olabileceğini düşündüm. –

+0

Sonuçta while döngüsüyle devam ediyor! Teşekkürler bir ton! –

+0

@AlexS Sayıların üzerinde yineleme yapıyorsanız, bu iyi - eğer bu sayıları listeler için endeksler olarak kullanıyorsanız veya lütfen, bunu yapma. Dizine göre yineleme her şekilde kötüdür. –

20

Yineleyiciyi bir adaya atamak en iyi yoldur - bir yineleyicinin karşısındaki yinelemeli olması (yinelenen bir değişiklik - örneğin bir liste - her seferinde yineleme yaptığınızda baştan başlar). Bu durumda, sadece the iter() built-in function kullanın:

numbers = iter(range(100)) 

Sonra adını kullanarak döngü içine ilerlemeden. Bunu yapmanın en iyi yolu the itertoolsconsume() recipe - hızlı olduğu için ( itertools işlevini kullanır) yinelemenin düşük düzey kodda olmasını sağlamak, değerleri çok hızlı tüketme işlemini yapmak ve tüketilen değerleri depolayarak belleği kullanmaktan kaçınır.):

numbers = iter(range(100)) 
for i in numbers: 
    ... 
    if some_check(i): 
     consume(numbers, 3) # Skip 3 ahead. 
+0

Python 3'te bile, bunun çalışması için * * 'nin 'range()' de 'iter() işlevini çağırdığını unutmayın. Python 3 'range()' nesnesi, bir yineleyici değil, bir dizidir (yinelenebilir). –

+0

@MartijnPieters İnanılmaz güzel nokta. Düzenlenen. Aralıklar üzerinde yineliyorum o kadar az ki, böyle olduğunu unuttum. –

+0

Harika cevap +1 –

4

Neden sadece kadar atlamak için değerini ayarlayın: bunu yaparak

from itertools import islice 
import collections 

def consume(iterator, n): 
    "Advance the iterator n-steps ahead. If n is none, consume entirely." 
    # Use functions that consume iterators at C speed. 
    if n is None: 
     # feed the entire iterator into a zero-length deque 
     collections.deque(iterator, maxlen=0) 
    else: 
     # advance to the empty slice starting at position n 
     next(islice(iterator, n, n), None) 

, gibi bir şey yapabilirim? Gibi:

skip_until = 0 
for i in range(100): 
    if i < skip_until: 
     continue 
    if SOME_CONDITION: 
     skip_until = i + 10 
    DO_SOMETHING() 
SOME_CONDITION ne olursa olsun atlamak ve DO_SOMETHING() gerçek döngü içeriği olan sebep olduğu

? döngüler olsa sadece üzgün iken

+0

+1, 'devam 'en az kıvrık yoldur. – 2rs2ts

+0

Bu, Python'da yürütülmesi gereken döngü ve her seferinde atanan ismi gerektirdiğine dikkat çekiyor - çoğu durumda bir problem olması muhtemel olmasa da, bu anlamda çok daha az verimlidir. –

+0

Evet, ama basit bir cevap istediğini düşündüğüm sorunun sadeliği göz önüne alındığında; Yineleyicilerle uğraşmak, döngüler/atlamalar küçükse, fazlalık gibi görünüyor. –

-2
for i in range(0, 100, 10): 
    print(i) 

yazdırır 0, 10, 20 ...

+1

Merhaba, bu ilk 10 değerleri atlamasa da, askerin ** ** 'de ** iken keyfi bir değere nasıl atlayacağını bilmeye daha çok ilgi duyduğunu düşünüyorum. Örnek için en iyi cevaba bakınız. – seth

+0

Bunun için kesinlikle python 3.3'e ihtiyacınız yok. –