Python Forum
Trying to access next element using Generator(yield) in a Class
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Trying to access next element using Generator(yield) in a Class
#1
I have created a Class and used generator in a method which is supposed to yield even numbers between start and stop range. When trying to use next() of yield from the Class Obj, it is printing the same number. Is this not the right way to access?

# Creating Class Evem
class Even:
    # Constructor
    def __init__(self, start, stop, reverse=False):
        self.start = start
        self.stop = stop
        self.reverse = reverse
        # self.nums = []

    # Creating filter method using yeild/Generator
    def filter_even(self):
        for i in range(self.start, self.stop + 1):
            if i % 2 == 0:
                yield i


# Creating an Obj of class Even
even_nums = Even(10, 50, False)

# Making sure what's in the obj I have created
print(even_nums.__dict__)
# {'start': 10, 'stop': 50, 'reverse': False}


# Trying to print the yield result one by one
print(even_nums.filter_even().__next__())
print(even_nums.filter_even().__next__())
print(even_nums.filter_even().__next__())
print(even_nums.filter_even().__next__())

# Q: Why is printing the same element??
# 10
# 10
# 10
# 10
Am I not calling it the right way?
print(even_nums.filter_even().__next__())
Reply
#2
Calling __next__ directly is not the best idea.

This line will call the function, which returns a generator.
The generator keeps the state. Then you're calling next on the generator, which yields the first result.
even_nums.filter_even().__next__()
But the generator is afterwards garbage collected because you have no reference to it.

  1. even_nums = Even(10, 50, False)
    for num in even_nums.filter_even():
        print(num)
        # only printing
  2. results = []
    even_nums = Even(10, 50, False)
    for num in even_nums.filter_even():
        print(num)
        results.append(num)
        # printing and appending to results
  3. even_nums = Even(10, 50, False)
    result = list(even_nums.filter_even())
  4. even_nums = Even(10, 50, False)
    result = tuple(even_nums.filter_even())
  5. even_nums = Even(10, 50, False)
    result = set(even_nums.filter_even())

You can also convert the class into an iterator iterable:
class Even:
    def __init__(self, start, stop):
        self.start = start
        self.stop = stop

    def __iter__(self):
        for i in range(self.start, self.stop + 1):
            if i % 2 == 0:
                yield i


even_numbers = Even(10, 20)
result = list(even_numbers)
print(result)
This is a boring class. So if the only functionality is to filter out even numbers, you can turn it into a function/generator.


def filter_even_numbers(sequence):
        for number in sequence:
            if number % 2 == 0:
                yield number


numbers = [1,2,3,4,5,6]
result = list(filter_even_numbers(numbers))
If you need to select a start and stop index of your sequence, you can do it with the subscription:
numbers = [1,2,3,4,5,6]
numbers_to_process = numbers[1:]
# from index 1 to ...

result = list(filter_even_numbers(numbers_to_process))
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#3
(Oct-19-2020, 02:02 PM)DeaD_EyE Wrote: Calling __next__ directly is not the best idea.

This line will call the function, which returns a generator.
The generator keeps the state. Then you're calling next on the generator, which yields the first result.
even_nums.filter_even().__next__()
But the generator is afterwards garbage collected because you have no reference to it.

  1. even_nums = Even(10, 50, False)
    for num in even_nums.filter_even():
        print(num)
        # only printing
  2. results = []
    even_nums = Even(10, 50, False)
    for num in even_nums.filter_even():
        print(num)
        results.append(num)
        # printing and appending to results
  3. even_nums = Even(10, 50, False)
    result = list(even_nums.filter_even())
  4. even_nums = Even(10, 50, False)
    result = tuple(even_nums.filter_even())
  5. even_nums = Even(10, 50, False)
    result = set(even_nums.filter_even())

You can also convert the class into an iterator iterable:
class Even:
    def __init__(self, start, stop):
        self.start = start
        self.stop = stop

    def __iter__(self):
        for i in range(self.start, self.stop + 1):
            if i % 2 == 0:
                yield i


even_numbers = Even(10, 20)
result = list(even_numbers)
print(result)
This is a boring class. So if the only functionality is to filter out even numbers, you can turn it into a function/generator.


def filter_even_numbers(sequence):
        for number in sequence:
            if number % 2 == 0:
                yield number


numbers = [1,2,3,4,5,6]
result = list(filter_even_numbers(numbers))
If you need to select a start and stop index of your sequence, you can do it with the subscription:
numbers = [1,2,3,4,5,6]
numbers_to_process = numbers[1:]
# from index 1 to ...

result = list(filter_even_numbers(numbers_to_process))

Thanks for your patience and explaining it very clearly.
DeaD_EyE likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  yield usage as statement or expression akbarza 5 750 Oct-23-2023, 11:43 AM
Last Post: Gribouillis
  How can I access objects or widgets from one class in another class? Konstantin23 3 929 Aug-05-2023, 08:13 PM
Last Post: Konstantin23
  Using list comprehension with 'yield' in function tester_V 5 1,175 Apr-02-2023, 06:31 PM
Last Post: tester_V
  [Solved] Novice question to OOP: can a method of class A access attributes of class B BigMan 1 1,267 Mar-14-2022, 11:21 PM
Last Post: deanhystad
  dict class override: how access parent values? Andrey 1 1,594 Mar-06-2022, 10:49 PM
Last Post: deanhystad
  Access instance of a class Pavel_47 5 2,033 Nov-19-2021, 10:05 AM
Last Post: Gribouillis
  access share attributed among several class methods drSlump 0 1,038 Nov-18-2021, 03:02 PM
Last Post: drSlump
  Tuple generator, and function/class syntax quazirfan 3 3,757 Aug-10-2021, 09:32 AM
Last Post: buran
  Create Generator in the Class quest 1 2,088 Apr-15-2021, 03:30 PM
Last Post: jefsummers
  Yield generator weird output Vidar567 8 3,196 Nov-23-2020, 10:59 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020