Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Basic Object-Oriented Python Emulating Built-ins __iter__

does this only work if there is one instance attribute that you want to loop through?

if there was more than one list in the dealership class that you wanted to add to, then iterate through, would this be possible?

Megan Amendola
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Megan Amendola
Treehouse Teacher

I encourage you to test it out and see! This is a great way to test your ideas and theories and see what happens. Post back with what you discovered.

3 Answers

Megan Amendola
seal-mask
STAFF
.a{fill-rule:evenodd;}techdegree seal-36
Megan Amendola
Treehouse Teacher

I'm glad you tested it out! Here's what I tested:

class Car:
    def __init__(self):
        self.makes = ['ford', 'toyota', 'tesla', 'chevy']
        self.types = ['car', 'truck', 'van']

    def __iter__(self):
        yield from self.makes

car = Car()
for make in car:
    print(make)

# result
>>> ford
>>> toyota
>>> tesla
>>> chevy

Dunder iter works on an instance of the class itself. Then I tried:

class Car:
    def __init__(self):
        self.makes = ['ford', 'toyota', 'tesla', 'chevy']
        self.types = ['car', 'truck', 'van']

    def __iter__(self):
        yield from self.makes

    def __iter__(self):
        yield from self.types

car = Car()
for make in car:
    print(make)

# result
>>> car
>>> truck
>>> van

The second dunder iter overrode the first. Out of curiosity, I tried:

class Car:
    def __init__(self):
        self.makes = ['ford', 'toyota', 'tesla', 'chevy']
        self.types = ['car', 'truck', 'van']

    def __iter__(self):
        yield from self.makes
        yield from self.types


car = Car()
for make in car:
    print(make)

# result
>>> ford
>>> toyota
>>> tesla
>>> chevy
>>> car
>>> truck
>>> van

So then I got both lists printed out one after the other. But don't forget that they are lists and can therefore be iterated on themselves. For example:

class Car:
    def __init__(self):
        self.makes = ['ford', 'toyota', 'tesla', 'chevy']
        self.types = ['car', 'truck', 'van']


car = Car()
# access the list itself and then iterate
for make in car.makes:
    print(make)

# access the list itself and then iterate
for a_type in car.types:
    print(a_type)

# result
>>> ford
>>> toyota
>>> tesla
>>> chevy
>>> car
>>> truck
>>> van

You could also do something like this:

class Car:
    def __init__(self):
        self.makes = ['ford', 'toyota', 'tesla', 'chevy']
        self.types = ['car', 'truck', 'van']

    def yield_items(self, item):
        if item == 'makes':
            yield from self.makes
        elif item == 'types':
            yield from self.types


car = Car()
for make in car.yield_items('makes'):
    print(make)

for a_type in car.yield_items('types'):
    print(a_type)

What it comes down to is the structure and organization of your class. What do you want it to do? How do you want it to behave? What makes the most sense?

I hope this helps! That was a fun question to dive into

when i try to iterate through one specific list that i have added to, it loops through all the attributes (other lists) in the class. is there a way to specify the attribute (list) you want to iterate through?

thanks, i think you covered all ground!