Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于python迭代器的困惑_Python_Python 3.x_Python 2.7_Iterator_Iterable - Fatal编程技术网

关于python迭代器的困惑

关于python迭代器的困惑,python,python-3.x,python-2.7,iterator,iterable,Python,Python 3.x,Python 2.7,Iterator,Iterable,我练习迭代器越多,就越感到困惑。我对对象和类(我们唯一学过的东西,而不是继承)很有信心,但迭代器和生成器让我的脑子乱七八糟。非常感谢您的帮助 我有一些问题: 1) 在下面的代码中: class main(): def __init__(self): self.items=[1,2,3,4,5,6,7] self.index= 0 def __iter__(self): return self def __next__(

我练习迭代器越多,就越感到困惑。我对对象和类(我们唯一学过的东西,而不是继承)很有信心,但迭代器和生成器让我的脑子乱七八糟。非常感谢您的帮助

我有一些问题:

1) 在下面的代码中:

class main():
    def __init__(self):
        self.items=[1,2,3,4,5,6,7]
        self.index= 0

    def __iter__(self):
        return self 

    def __next__(self):
        self.index+=1

        return self.items[self.index]

a = main()

for i in a:
    print(i)  
  • 我们这里有两个人。一个在init中,它引用对象“a”,另一个由self返回。自我的真实数据类型是什么?它是main()类型还是迭代器类型
  • 类似于上面的问题-当我们给出donext(self)时,我们给next(类型(a)的迭代器)什么self
  • 如果由
    \uuu iter\uuuu
    返回的self after(也被next使用)是迭代器类型,那么如何访问
    self.index
  • 2) 在下面的代码中,我试图对特定的东西进行迭代,例如dictionary类中的键、值或项。 它正在抛出错误“迭代器”对象没有属性“索引”。 为什么self.index不能访问dictionary类的实例变量索引?

    class Pair():
        def __init__(self, key ,value):
            self.key = key
            self.value = value
    
    class Dictionary():
        def __init__(self):
            self.items =[]
            self.index = -1     ################## INDEX DEFINED HERE
    
        def __setitem__(self, key, value):
            for i in self.items:
                if i.key == key:
                    i.value = value
                    return
            self.items.append(Pair(key,value))
    
        def __keys__(self):
            return iterator(self, 'keys')
    
        def __values__(self):
            return iterator(self, 'values')
    
        def __items__(self):
            return iterator(self , 'items')
    
    class iterator():
        def __init__(self, object, typo):
            self.typo = typo
    
        def __iter__(self):
            return self
    
        def __next__(self):
            if self.typo == 'keys': 
                self.index +=1  #################### ERROR
                if self.index >= len(self.items):
                    raise StopIteration
                return self.items[self.index].keys
    
            ` # Similarly for keys and items as well`
    
    collins = Dictionary()
    
    collins['google'] = 'pixel'
    collins['htc'] = 'M8'
    collins['samsung'] = 'S9'
    
    
    for i in collins.__keys__():
        print(i)
    

    我用大量注释重写了您的代码,试图解释示例(1)中发生的事情

    class MainClass():
    定义初始化(自):
    #值“self”总是指我们当前正在处理的对象
    #开。在本例中,我们将实例化类的一个新对象
    #main类,因此self引用该新对象。
    #self.items是对象中名为items的实例变量
    #称为自我。
    self.items=[1,2,3,4,5,6,7]
    #我们不想在这里声明self.index。这有点微妙
    #重点。如果我们在这里声明索引,那么它将只在我们第一次
    #创建MainClass类的对象。我们实际上希望self.index
    #每次迭代对象时将其设置为零,因此应将其设置为零
    #在_iter__(self)方法中为零。
    #self.index=0
    定义(自我):
    #这是一个实例方法,它对的当前实例进行操作
    #MainClass(类MainClass的对象)。在以下情况下调用此方法:
    #我们在一个对象上开始迭代,所以如上所述,我们将
    #self.index为零。
    self.index=0
    回归自我
    定义下一个(自我):
    #这也是一个实例方法,它在当前
    #MainClass的实例。
    如果self.index

    我认为,在继续(2)之前回顾一下这一点,并仔细检查您对对象和类的了解,可能会有所帮助。我们在(2)中看到的第一个问题是,您将
    对象
    传递给
    迭代器
    类,但不要将其存储在任何位置,以便以后无法访问它。但是,当您更全面地理解了(1)中的所有问题时,您可能会发现您还有其他方法想要更改它。

    我用大量注释重写了您的代码,试图解释示例(1)中发生的事情

    class MainClass():
    定义初始化(自):
    #值“self”总是指我们当前正在处理的对象
    #开。在本例中,我们将实例化类的一个新对象
    #main类,因此self引用该新对象。
    #self.items是对象中名为items的实例变量
    #称为自我。
    self.items=[1,2,3,4,5,6,7]
    #我们不想在这里声明self.index。这有点微妙
    #重点。如果我们在这里声明索引,那么它将只在我们第一次
    #创建MainClass类的对象。我们实际上希望self.index
    #每次迭代对象时将其设置为零,因此应将其设置为零
    #在_iter__(self)方法中为零。
    #self.index=0
    定义(自我):
    #这是一个实例方法,它对的当前实例进行操作
    #MainClass(类MainClass的对象)。在以下情况下调用此方法:
    #我们在一个对象上开始迭代,所以如上所述,我们将
    #self.index为零。
    self.index=0
    回归自我
    定义下一个(自我):
    #这也是一个实例方法,它在当前
    #MainClass的实例。
    如果self.index
    我认为,在继续(2)之前回顾一下这一点,并仔细检查您对对象和类的了解,可能会有所帮助。第一个问题
    class MainClass():
        def __init__(self):
            # The value 'self' always refers to the object we are currently working
            # on. In this case, we are instantiating a new object of class
            # MainClass, so self refers to that new object.
            # self.items is an instance variable called items within the object
            # referred to as self.
            self.items = [1, 2, 3, 4, 5, 6, 7]
            # We do not want to declare self.index here. This is a slightly subtle
            # point. If we declare index here, then it will only be set when we first
            # create an object of class MainClass. We actually want self.index to be
            # set to zero each time we iterate over the object, so we should set it
            # to zero in the __iter__(self) method.
            # self.index = 0
    
        def __iter__(self):
            # This is an instance method, which operates on the current instance of
            # MainClass (an object of class MainClass). This method is called when
            # we start iteration on an object, so as stated above, we'll set
            # self.index to zero.
            self.index = 0
            return self
    
        def __next__(self):
            # This is also an instance method, which operates on the current
            # instance of MainClass.
            if self.index < len(self.items):
                self.index += 1
                return self.items[self.index - 1]
            else:
                # This is how we know when to stop iterating.
                raise StopIteration()
    
    
    a = MainClass()
    
    # a is now an object of class MainClass
    # Because we have implemented __iter__ and __next__ methods in MainClass,
    # objects of class MainClass are iterable, so a is also iterable.
    
    # When we say "for i in a" this is like shorthand for  saying "a.__iter__()"
    # and then "i = a.__next__()" until we raise
    # a StopIterationException
    
    # Here we are iterating over the result of a.__iter__() until a.__next__()
    # raises a StopIterationException
    for i in a:
        # Here we are printing the value returned by a.__next__()
        print(i)
    
    class Main:
        def __init__(self):
            self.items = list(range(1, 8))
            self.length = len(self.items)
    
        def __iter__(self):
            return MainIterator(self)
    
    class MainIterator:
        def __init__(self, iterable):
            self.iterable = iterable
            self.index = 0
    
        def __next__(self):
            if self.index >= self.iterable.length:
                raise StopIteration
    
            self.index += 1
            return self.iterable.items[self.index - 1]
    
    class Main:
        def __init__(self):
            self.items = list(range(1, 8))
            self.length = len(self.items)
    
        def __iter__(self):
            self.index = 0
            return self
    
        def __next__(self):
            if self.index >= self.length:
                raise StopIteration
    
            self.index += 1
            return self.items[self.index - 1]
    
    a = Main()
    
    ## recreating the for in loop
    
    itr = a.__iter__()
    
    while True:
        try:
            print(itr.__next__())
        except StopIteration:
            break
    
    class Pair:
    
        def __init__(self, key, value):
            self.key = key
            self.value = value
    
        ## you need this to display your class in a meaningful way
        def __repr__(self):
            return f'{__class__.__name__}({self.key}, {self.value})'
    
    class Dictionary:
    
        def __init__(self):
            self.items = []
            self.length = len(self.items)
    
        def add(self, objects):
            self.items.append(objects)
            self.length += 1
    
        def __iter__(self):
            self.index = 0
            return self
    
        def __next__(self):
            if self.index >= self.length:
                raise StopIteration
    
            self.index += 1
            return self.items[self.index - 1]
    
    a = Dictionary()
    
    a.add(Pair('up', 'above'))
    a.add(Pair('down', 'below'))
    
    for i in a:
        print(i.key)
        print(i.value)
    
    up
    above
    down
    below
    
    class Pair():
        def __init__(self, key, value):
            self.key = key
            self.value = value
    
    
    class dictionary():
        def __init__(self):
            self.items = []
    
        def add(self, objects):
            self.items.append(objects)
    
        def __keys__(self):
            return iterator(self, 'keys')
    
        def __values__(self):
            return iterator(self, 'values')
    
    class iterator():
        def __init__(self, to_be_iterated , over_what):
            self.to_be_iterated = to_be_iterated
            self.over_what = over_what
    
    
        def __iter__(self):
            self.index = -1
            return self
    
        def __next__(self):
            self.index += 1
            if self.over_what == 'keys':
                try:
                        return self.to_be_iterated.items[self.index].key
                except Exception:
                    raise StopIteration
    
            elif self.over_what == 'values':
                try:
                        return self.to_be_iterated.items[self.index].value
                except Exception:
                    raise StopIteration
    
    
    collins = dictionary()
    
    collins.add(Pair('up', 'above'))
    collins.add(Pair('down', 'below'))
    
    for i in collins.__keys__():
        print(i)
    
    for i in collins.__values__():
        print(i)