2017-06-19 22 views
7

Próbuję uruchomić program Pythona z pętlą for, która ma zmienną i zwiększoną o 1 za każdym razem od 1 do długości mojej listy. W Javie, mój kod, który Idę może wyglądać tak:Czy istnieje sposób wpływania na licznik zakresu w Pythonie?

for (int i = 0; i < array.length; i++) { 
     //code goes here 
     i += //the number i want it to go up by 
} 

To rzeczywiście wpływa na mój licznik sposób zamierzony i pozwala mi skutecznie pominąć numery w mojej pętli i chcę spróbować uruchomić podobny program, ale w python. Czy jest jakiś sposób, aby to zrobić z wbudowaną funkcją Pythona lub czy muszę użyć pętli while i licznika, aby samemu to zasymulować, jeśli chcę, aby Python działał w ten sposób?

Odpowiedz

4

Musisz pętli while dla tego:

i = 0 
while i < len(myArray): 
    # do stuff 
    if special_case: i+= 1 
    i += 1 
1

Nie można modyfikować krok połowie liczyć, ale jeśli przechodzeniu jest stała, można określić go na początku:

# the default 
>>> range(1, 10) 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 

# step 2 
>>> range(1, 10, 2) 
[1, 3, 5, 7, 9] 

Można również krok wstecz:

>>> range(10, 0, -1) 
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1] 

Jeśli twoja sprawa jest, niestety, nie taka, w której krok jest stały przez cały czas iteracji, z pewnością będziesz potrzebował pętli, jak słusznie przypuszczasz.

+0

Myślę, że OP chce dynamicznie wpływać na zmienną pętli podczas wykonywania - nie zmienia statycznie struktury pętli – inspectorG4dget

+0

@ inspektorG4dget To jest opcja, jeśli affe Jednak ctation był stały. Edytowane. –

1

W python jest bardzo podobny z Java. Możesz dynamicznie zwiększać swój licznik na podstawie różnych warunków:

x = 1 
while x < 100: 
    if condition1: 
     x += 1 
    elif condition2: 
     x += 2 
    else: 
     x += 3 
0

Będziesz szczęśliwszy z pętlą while. Można zrobić coś jak

l = list(range(min_count,max_count)) 
for i in l: 

i modyfikować l podczas pętli. Ale uzyskanie tego jest trudne. Można również utworzyć obiekt iteracji za pomocą metody skip i wywołać to podczas pętli.

class SkipRange: 

    def __init__(self, minc, maxc, step): 
     self.count = minc 
     self.maxc = maxc 
     self.step = step 

    def __iter__(self): return self 

    def __next__(self): 
     if self.count > self.maxc: raise StopIteration 
     c = self.count 
     self.count += self.step 
     return c 

    def skip(self, num = 1): self.count += num 

Niewytestowana i całkowicie z góry głowy bmy; debugowanie jest pozostawione jako ćwiczenie każdemu zirytowanemu podczas pętli wystarczającej do przejścia na tę trasę. Myślę, że to bardziej ilustruje to, co dzieje się pod kołdrą.

s = SkipRange(min_count,max_count) 
for i in s: 
    # do stuff 
    s.skip(3) #skip next 3 items 

Ale pętla while jest bardziej czytelna iw większości przypadków łatwiejsza.

1

W języku Python można tworzyć jednokierunkowe iteratory z wbudowaną funkcją iter. Dzięki temu możesz zadzwonić pod numer next, aby skutecznie pominąć krok.

Aby to zrobić z wielu kroków, gdy itertools recipies definiuje consume funkcję:

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) 

w tym przypadku, możemy zrobić:

import itertools 

def skip(iterator, n): 
    next(itertools.islice(iterator, n, n), None) 

range_iter = iter(range(len(ls))) 

for i in range_iter: 
    # ... 
    if custom_condition: 
     skip(range_iter, 2) # Or any number. 

działa to również bezpośrednio Iterowanie nad listami :

ls_iter = iter(ls) 

for i in ls_iter: 
    # ... 
    if custom_condition: 
     skip(ls_iter, 3) 

Są bardzo wydajne, ponieważ wykorzystują wbudowane typy i funkcje.

2

(Uwaga: nie używać tego kodu dla każdego zdalnie poważnego celu)

Problem z modyfikując wartość i w kodzie to: normalnie, zadania (w tym rozszerzona zadania, +=) wykonane z lokalnymi niezmienne wartości są widoczne tylko w zasięgu lokalnym. Wnętrze range nie znajduje się w zasięgu lokalnym. Podczas ponownego przypisywania i implementacja range nie ma możliwości o tym wiedzieć.

Normalnie.

Ale Python ma wbudowany moduł o nazwie inspect, który eksponuje różnego rodzaju informacje o twoim programie, które normalnie nie byłyby dostępne w czasie wykonywania. Obejmuje to wartości zmiennych w ramkach, które w innym przypadku byłyby całkowicie niedostępne.

Z pogwałceniem dobrych zasad programowania i praw natury, możemy napisać funkcję podobną do zakresu, która przebija zasłonę niewiedzy, i kradnie wartość i z kontekstu wywołującego, podobnie jak Prometheus ukradł ogień z szczyt Olimpu. (Uwaga:. Przypomnieć, co się dzieje z Prometeusza na końcu tej historii)

import inspect 
import re 

def mutable_range(max): 
    x = 0 
    while x < max: 
     yield x 
     record = inspect.stack()[1] 
     frame = record[0] 
     source_lines = record[4] 
     iterator_name = re.match(r"\s*for (\w+) in mutable_range", source_lines[0]).group(1) 
     peek = frame.f_locals[iterator_name] 
     if peek != x: 
      x = peek 
     else: 
      x += 1 

for i in mutable_range(10): 
    print(i) 
    if i == 3: 
     i = -10 
    if i == -8: 
     i = 6 

Wynik:

0 
1 
2 
3 
-10 
-9 
-8 
6 
7 
8 
9 

(Uwaga: Autor nie ponosi odpowiedzialności za korzystanie z kodu, a następnie karę swojej pychy przez orły żywiące się twoją wątrobą przez całą wieczność)

Powiązane problemy