2017-02-05 1 views
0

Мне просто интересно, какой самый «питонический» способ увеличивать варибель x на всем пути от 0 до 100, а затем, когда x достигает 100, deincrement обратно в 0, затем снова к 100 в цикле снова и снова ...Приращение переменной до 100, затем деинкрементация на 0 и обратно в цикле

Что-то вроде этого:

x = 0 
while True: 
    if x < 100: 
    x += 1 
    elif x == 100: 
    x -= 1 

NB: Приведенный выше код не работает, поэтому мой вопрос. :)

Каков самый простой способ сделать это - не обязательно самый короткий код, не ища один лайнер, просто очень хороший код.

+2

Это не делает то, что вы хотите. 'elif x == 100:' уменьшит его до 99, в какой точке 'if x <100:' is 'True', поэтому он снова увеличивается. Более важно убедиться, что что-то работает, прежде чем пытаться оптимизировать. – roganjosh

+0

Да, я понимаю, что код выше не работает. – zzoop

+0

Ну, ваш первоначальный вопрос не говорил об этом. Удачи найти какие-либо разъяснения в том, что «pythonic» в том, что было предложено в качестве ответов. Я бы оценил функциональность выше питонизма (это слово?), Но там вы идете. – roganjosh

ответ

1

Как насчет попробовать это?

x = 0 
inc = 1 
while True: 
    # do your job here 
    if x == 0: 
    inc = 1 
    elif x == 100: 
    inc = -1 
    x += inc 
+0

На самом деле, мне нравится этот метод лучше, поэтому я изменил принятый ответ. – zzoop

1

Нет ничего плохого в использовании двух петель!

while True: 
    for x in range(100): 
     do_something(x) 
    for x in range(98, 0, -1): 
     do_something(x) 

Или вы могли бы использовать переменную для отслеживания, в каком направлении вы собираетесь:

delta = 1 
x = 0 
while True: 
    do_something(x) 
    x += delta 
    if x < 1 or x > 99: 
     delta = -delta 
2

Прежде всего кода не работает: он будет считать до 100, а затем обмен между 99 и 100. Таким образом: 1,2,3, .., 99,100,99,100,99 ...

на самом деле самый Pythonic способ, вероятно не для увеличения/уменьшения на всех, но использовать два range s:

while True: 
    for x in range(101): 
     pass 
     #do something with x 
    for x in range(99,0,-1): 
     pass 
     #do something with x 

Или построить бесконечное генератор с :

generator = itertools.cycle(itertools.chain(range(101),range(99,0,-1))) 

, а затем вы можете использовать его как:

for x in generator: 
    pass 
    #do something with x 

экземпляра Fr (я здесь использовать 2, потому что это делает ответ более компактный):

for x in itertools.cycle(itertools.chain(range(3),range(1,0,-1))): 
    print(x) 

будет производить:

0 
1 
2 
1 
0 
1 
2 
1 
0 

цикл будет повторяться бесконечно.

способ исправить код, однако было бы добавить направление, но это, вероятно, не очень Pythonic:

x = 0 
dr = True 
while True: 
    if dr: 
     x += 1 
     if x >= 100: 
      dr = False 
    else: 
     x -= 1 
     if x <= 0: 
      dr = True 
    #do something with x 
+0

Хороший призыв к использованию двух диапазонов - намного больше Pythonic. –

+0

Спасибо - да, мне нравятся два диапазона. Я принял этот ответ, поскольку у него есть хорошее объяснение для нескольких решений. – zzoop

0

Ну, ваше текущее решение не будет работать точно - вы будете деинкремент назад до 99, а затем между 99 и 100.

Самый простой может быть, чтобы добавить direction флаг, например:

x = 0 
isIncreasing = True 
while True: 
    if isIncreasing = True: 
    x += 1 
    if x == 100: 
     isIncreasing = False 
    else: 
    x -= 1 
    if x == 0: 
     isIncreasing = True 

Я есть еще «одна линия» способ сделать это с itertools (см.выше сообщений), но это было бы самое «прямое» решение в вашем текущем случае. Конечно, то, что вы действительно ищете, это generator.

3

Я считаю однострочечники просто ... так что по этому поводу:

Python 2:

from itertools import * 
ups_and_downs = cycle(chain(xrange(100), xrange(100, 0, -1))) 

Python 3:

from itertools import * 
ups_and_downs = cycle(chain(range(100), range(100, 0, -1))) 

(отредактирован, чтобы удалить разовая ошибка)

+0

Обратите внимание, что ваши диапазоны не симметричны. – jonrsharpe

+0

Вы правы. И, как результат, итерация вернулась слишком рано. Цепочка и цикличность '[0, 100)' и '[100, 0)' должны работать лучше и выглядеть лучше тоже;) – mkorvas

+0

Я бы поднял, но у меня закончились: oS – jonrsharpe

0

ну, так как никто другой не делает этого, почему бы не какой-нибудь генератор весело!

def lazy_forever_and_ever(hi, lo, start=0, step=1): 
    x = start 
    vals = {hi: lo, lo: hi} 
    target=lo 
    while True: 
     if x == target: 
      target = vals[target] 
     if x >= target: 
      yield x 
      x -= step 
     elif x <= target: 
      yield x 
      x += step 

if __name__ == '__main__': 
    _4eva = lazy_forever_and_ever(0, 10, 0, 1) 
    print([next(_4eva) for _ in range(20)]) 

# output 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1] 
Смежные вопросы