简体   繁体   中英

How to fix the __iter__ method

from collections import defaultdict
from goody import type_as_str

class Bag:
    def __init__(self, i=None):
        self.bag = []
        if i == None:
            pass  # i is None, do nothing after create empty bag
        elif type(i)==list:
            self.bag.extend(i) # append whole list i into bag with extend method
        else:
            self.bag.append(i) # append single item i into bag 

    def __repr__(self):
        for s in self.bag :
            return s

    def __str__(self):
        for s in self.bag :
            return s

    def __len__ (self):
        if 'Bag()' in self.bag:
            return 0
        else:
            return len(self.bag)
    def unique(self):
        l = []
        if len(self.bag) == 0:
            return 0
        else:
            for x in self.bag:
                if x not in l:
                    l.append(x)
                else:
                    continue
            return len(l)

    def __contains__ (self,i):
        if i in self.bag:
            return True
        else:
            return False

    def count(self,i):
        return self.bag.count(i)

    def add(self,i):
        self.bag.append(i)

    def __add__(self,i):
        for x in i:
           self.bag.append(x)

    def remove(self,i):
        if i not in self.bag:
            raise ValueError
        for x in self.bag:
            if x == i:
                self.bag.remove(x)
                break


    def __eq__ (self,i):
        return self.bag == i 

    def __ne__ (self,i):
        return self.bag != i

    def __iter__(self):
        class PH_iter:
            def __init__(self,i):

                self.l = i

            def add(self,i):
                self.l.append(i)

            def remove(self,i):
                self.l.pop(i)

        return PH_iter(self.l)




if __name__ == '__main__':
#driver tests
import driver
driver.default_file_name = 'bsc1.txt'
#     driver.default_show_exception= True
#     driver.default_show_exception_message= True
#     driver.default_show_traceback= True
driver.driver()

Bag function generally returns a list. Writing Bag() constructs an empty bag. Writing Bag(['d','a','b','d','c','b','d']) construct a bag with one 'a', two 'b's, one 'c', and three 'd's.

The iter method is supposed to be defined in the bag class to add or remove item from the list.

The input is:

# Test iterator
e-->[i for i in sorted(b)]-->['a', 'b', 'b', 'c', 'd', 'd', 'd']
c-->i = iter(b)
c-->b.add('d')
c-->b.remove('a')
e-->[i for i in sorted(b)]-->['b', 'b', 'c', 'd', 'd', 'd', 'd']
e-->[i for i in sorted(x for x in i)]-->['a', 'b', 'b', 'c', 'd', 'd', 'd']

The error i got is:

 94 # Test iterator
 95 *Error: [i for i in sorted(b)] raised exception AttributeError: 'Bag' object has no attribute 'l'
 96 *Error: i = iter(b) raised exception AttributeError: 'Bag' object has no attribute 'l'
 99 *Error: [i for i in sorted(b)] raised exception AttributeError: 'Bag' object has no attribute 'l'
 100 *Error: [i for i in sorted(x for x in i)] raised exception NameError: name 'i' is not defined

Can anyone help me to fix the iter function to make it work? Many thanks.

In __iter__ , this line is causing the runtime error

return PH_iter(self.l)

It should be

return PH_iter(self.bag)

And this implementation is going to give you some surprise after iteration because it actually modified the data content of self.bag

You can improve it by

def __iter__(self):
    class PH_iter:
        def __init__(self,i):
            self.l = list(i)  # make a copy of the list i

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM