2015-05-14 4 views
2

Я только что узнал об итераторах на Python, однако мне сложно их реализовать.Использование итератора в python?

Я пытаюсь написать класс, так что этот цикл работ:

odds = OddNumbers(13) 
    for i in odds: 
     print(i) 

Я хочу написать функцию ИТЭР() и следующую функцию(), чтобы сделать это.

До сих пор у меня есть:

class OddNumbers: 

    def __init__(self, number): 
     self.number = number 

    def __iter__(self): 
     return self 

    def __next__(self): 
     current = self.number 
     if self.number%2 == 0: 
      return current 
     else: 
      raise StopIteration 

Но на данный момент это не возвращается ничего. Я ожидаю, что выход будет

1 
3 
5 
7 
9 
11 
13 

Помощь?

+0

Что вы пытаетесь сделать? У вас есть только один элемент. Зачем вам этот класс быть итерируемым? – thefourtheye

+1

Какие числа должен печатать пример кода? – user2357112

+0

Если вы начинаете с нечетного числа, то '__next__' будет только' raise StopIteration'. Если вы начнете с четного числа, оно вернет только это число. Возможно, вы имели в виду '__next__', чтобы уменьшить' self.number' каждый раз? –

ответ

1

Вам нужен другой переменной для отслеживания текущего номера:

def __init__(self, number): 
    self.number = number 
    self.current = 1 

Тогда вам нужно сравнить его с окончанием числа, и, возможно, увеличить его:

def __next__(self): 
    if self.current > self.number: 
     raise StopIteration 
    current = self.current 
    self.current += 2 
    return current 
+0

Большое спасибо! Это решило мою проблему! На одном этапе у меня была другая переменная для отслеживания количества итераций, за исключением того, что я не инициализировал ее с помощью метода __init__, я только представил ее в __next__. Еще раз спасибо! – ASm

+0

Вы не должны указывать OP весь ответ, это не учит их чему-либо. – augurar

+1

@augurar, ОП показал усилие и разместил реальный код, поэтому ответ правильный ответ. Комментарий показал, что он узнал об этом. –

3

Ваш объект должен отслеживать его состояние и обновлять его при вызове __next__.

class OddNumbers(object): 
    def __init__(self, number): 
     self.current = ... 
     self.number = number 

    def __iter__(self): 
     return self 

    def __next__(self): 
     # Update self.current 
     # If the limit has been reached, raise StopIteration 
     # Otherwise, return something 
0

Существует, вероятно, намного более чистый способ сделать это, но вот быстрый удар:

class OddNumbers: 

    def __init__(self, number): 
     self.number = number 

    def __iter__(self): 
     self.current = self.number 
     return self 

    def __next__(self): 
     if self.current > 0: 
      if self.current % 2 == 0: 
       self.current -= 1 
      self.current -= 1 
      return self.current + 1 
     raise StopIteration 
0

Это даст вам объект, похожий на итератор, который предоставляет четные или нечетные числа. Однако он не удовлетворит вашу семантику цикла for, поскольку это не истинный итератор.

class NumberIterator(object): 
    """Returns simple even/odd number iterators.""" 
    def __init__(self, current): 
     self.current = current 
    def next(self): 
     self.current += 2 
     return self.current 
    @classmethod 
    def getOddIterator(cls): 
     return cls(-1) # start at 1 
    @classmethod 
    def getEvenIterator(cls): 
     return cls(0) # start at 2 


    odd_numbers = NumberIterator.getOddIterator() 
    even_numbers = NumberIterator.getEvenIterator() 

    odd_numbers.next() # Returns 1 
    odd_numbers.next() # Returns 3 
Смежные вопросы