Питон новичок: для J в диапазоне - PullRequest
0 голосов
/ 07 июня 2018

Я новичок в изучении Python в эти дни.Читая книгу, я нашел строку кода, которую не могу понять.См. Строку 46 в методе print_progression (), print ('' .join (str (next (self)) для j в диапазоне (n))).

class Progression:
    '''Iterator producing a generic progression.
    Default iterator produces the whole number, 0, 1, 2, ...
    '''

def __init__(self, start = 0):
    '''
    Initialize current to the first value of the progression.
    '''
    self._current = start

def _advance(self):
    '''
    Update self.current to a new value.
    This should be overriden by a subclass to customize progression.
    By convension, if current is set to None, this designates the
    end of a finite progression.
    '''
    self._current += 1

def __next__(self):
    '''
    Return the next element, or else raise StopIteration error.
    '''
    # Our convention to end a progression
    if self._current is None:
        raise StopIteration()
    else:
        # record current value to return
        answer = self._current
        # advance to prepare for next time
        self._advance()
        # return the answer
        return answer

def __iter__(self):
    '''
    By convention, an iterator must return itself as an iterator.
    '''
    return self

def print_progression(self, n):
    '''
    Print next n values of the progression.
    '''
    print(' '.join(str(next(self)) for j in range(n)))


class ArithmeticProgression(Progression): # inherit from Progression
    pass

if __name__ == '__main__':
    print('Default progression:')
    Progression().print_progression(10)

'''Output is
Default progression:
0 1 2 3 4 5 6 7 8 9 10'''

Понятия не имею, как дальше (self) и j работает.

  1. Я думаю, что это должно быть str (Progression.next ()).(решено)

  2. Я нигде не могу найти j.Для чего нужен j?Почему бы не использовать цикл while, например while Progression.next () <= range (n)? </p>

Для моей последней мысли это должно быть

print (''.join (str (next (self)), а next (self) <= range (n))) </p>

Сохранить этого новичка.

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Я думаю, что @csevier добавил разумное обсуждение вашего первого вопроса , но я не уверен, что на ваш вопрос ответили так же ясно, как вы, исходя из ваших комментариев, поэтому я собираюсь попробовать другойугол.

Допустим, вы сделали:

for x in range(10):
    print(x)

Это вполне понятно - вы создали список [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] и по очереди вывели каждое из значений в этом списке.Теперь предположим, что мы хотели просто напечатать "hello" 10 раз;хорошо, мы могли бы изменить наш существующий код очень просто:

for x in range(10):
    print(x)
    print('hello')

Умм, но теперь x портит наш вывод.Нет синтаксиса:

do this 10 times:
    print('hello')

.Мы можем использовать цикл while, но это означает определение дополнительного счетчика:

loop_count = 0
while loop_count < 10:
    print('hello')
    loop_count += 1 

Это багаж.Таким образом, лучшим способом было бы просто использовать for x in range(10): и просто не беспокоиться о print(x);Ценность заключается в том, чтобы заставить наш цикл работать, а не потому, что он действительно полезен любым другим способом.Это то же самое для j (хотя я использовал x в своих примерах, потому что я думаю, что вы с большей вероятностью столкнетесь с этим в уроках, но вы можете использовать практически любое имя, которое захотите).Кроме того, циклы while обычно используются для циклов, которые могут выполняться бесконечно, а не для итерации по объекту с фиксированным размером: см. здесь .

0 голосов
/ 07 июня 2018

Добро пожаловать в сообщество Python!Это большой вопрос.В Python, как и в других языках, есть много способов сделать что-то.Но когда вы следуете соглашению, которое делает сообщество Python, это часто называют «питоническим» решением.Метод print_progression является общим питоническим решением для итерации определенной пользователем структуры данных.В приведенном выше случае давайте сначала объясним, как работает код, а затем, почему мы так поступили бы.

Ваш метод print_progression использует тот факт, что ваш класс Progression реализует итерационный протокол, реализуя методы next и iter dunder / magic.Поскольку они реализованы, вы можете выполнять итерацию вашего экземпляра класса как внутри, так и после next (self), и извне next (Progression ()), что именно то, что вы получили с вашим номером 1. Поскольку этот протокол уже реализован, этотКласс может быть использован в любом встроенном контексте итератора и генератора для любого клиента!Это полиморфный раствор.Он также используется внутри, потому что вам не нужно делать это двумя разными способами.

Теперь для неиспользуемой переменной J.Они просто используют это, чтобы они могли использовать цикл for.Простое использование range (n) вернуло бы itterable, но не повторялось по нему.Я не совсем согласен с тем, что авторы используют переменную с именем J, часто чаще обозначают неиспользуемую переменную, которая используется просто потому, что она должна быть в качестве подчеркивания.Мне нравится это немного лучше:

 print(' '.join(str(next(self)) for _ in range(n)))
...