Python 迭代器、iterable和迭代到底是什么?

Python 迭代器、iterable和迭代到底是什么?,python,iterator,iteration,terminology,iterable,Python,Iterator,Iteration,Terminology,Iterable,Python中“iterable”、“iterator”和“iteration”最基本的定义是什么 我读过多个定义,但我无法确定确切的含义,因为它仍然无法理解 有人能帮我解释一下外行术语中的3个定义吗?iterable是一个对象,它有一个\uuu iter\uuuu()方法。它可能会重复多次,例如list()s和tuple()s 迭代器是进行迭代的对象。它由\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

Python中“iterable”、“iterator”和“iteration”最基本的定义是什么

我读过多个定义,但我无法确定确切的含义,因为它仍然无法理解


有人能帮我解释一下外行术语中的3个定义吗?

iterable是一个对象,它有一个
\uuu iter\uuuu()
方法。它可能会重复多次,例如
list()
s和
tuple()
s

迭代器是进行迭代的对象。它由
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

迭代是调用this
next()
resp的过程<代码>\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

例如:

>>> a = [1, 2, 3] # iterable
>>> b1 = iter(a) # iterator 1
>>> b2 = iter(a) # iterator 2, independent of b1
>>> next(b1)
1
>>> next(b1)
2
>>> next(b2) # start over, as it is the first call to b2
1
>>> next(b1)
3
>>> next(b1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> b1 = iter(a) # new one, start over
>>> next(b1)
1
>a=[1,2,3]#iterable
>>>b1=iter(a)#迭代器1
>>>b2=iter(a)#迭代器2,独立于b1
>>>下一页(b1)
1.
>>>下一页(b1)
2.
>>>下一步(b2)#重新开始,因为这是对b2的第一次调用
1.
>>>下一页(b1)
3.
>>>下一页(b1)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
停止迭代
>>>b1=iter(a)#新的,重新开始
>>>下一页(b1)
1.

我不认为您可以获得比的简单得多的功能,但是我将尝试:

  • Iterable是可以迭代的东西。在实践中,它通常意味着一个序列,例如有一个开始和一个结束的东西,以及通过某种方式遍历其中所有项目
  • 您可以将迭代器看作一个辅助伪方法(或伪属性),它给出(或保存)iterable中的下一个(或第一个)项。(实际上,它只是一个定义方法
    next()
    )的对象)


  • 迭代最好的解释可能是《韦氏大词典》:

b:计算机指令序列的重复 次数或直到满足条件-比较递归


迭代是一个通用术语,用于一个接一个地获取某物的每一项。任何时候使用循环(显式或隐式)遍历一组项,这就是迭代

在Python中,iterableiterator具有特定的含义

iterable是一个对象,它有一个
\uuuuuuuuuuuuuuuuuuuuuu
方法,该方法返回一个迭代器,或者定义一个
\uuuuuuuu getitem\uuuuuuuuuuuuuuuu
方法,该方法可以从零开始获取顺序索引(并在索引不再有效时引发一个
索引器)。因此,iterable是一个对象,您可以从中获得迭代器

迭代器是具有
next
(Python 2)或
\uuuuuuuuuuuuuuuuuuuuuuuuuuuu
(Python 3)方法的对象

无论何时在Python中使用
for
循环、或
映射、或列表理解等,都会自动调用
next
方法从迭代器中获取每个项,从而完成迭代的过程


一个开始学习的好地方是和。了解基本知识后,请尝试。

以下是我在教授Python课程时使用的解释:

一个重要的例子是:

  • 可以循环的任何内容(即,可以循环字符串或文件)或
  • 可以出现在for循环右侧的任何内容:
    对于iterable:…
    中的x,或
  • 您可以使用
    iter()
    调用任何将返回迭代器的内容:
    iter(obj)
  • 一个对象,定义返回新迭代器的, 或者它可能有一个适合索引查找的
    \uuu getitem\uu
    方法
迭代器是一个对象:

  • 具有在迭代过程中记住其所在位置的状态
  • 使用
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    方法:
    • 返回迭代中的下一个值
    • 将状态更新为指向下一个值
    • 通过提升
      StopIteration
  • 也就是说,self-iterable(这意味着它有一个返回self
方法)

注:

  • Python 3中的
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
  • 内置函数
    next()
    对传递给它的对象调用该方法
例如:

>>> s = 'cat'      # s is an ITERABLE
                   # s is a str object that is immutable
                   # s has no state
                   # s has a __getitem__() method 

>>> t = iter(s)    # t is an ITERATOR
                   # t has state (it starts by pointing at the "c"
                   # t has a next() method and an __iter__() method

>>> next(t)        # the next() function returns the next value and advances the state
'c'
>>> next(t)        # the next() function returns the next value and advances
'a'
>>> next(t)        # the next() function returns the next value and advances
't'
>>> next(t)        # next() raises StopIteration to signal that iteration is complete
Traceback (most recent call last):
...
StopIteration

>>> iter(t) is t   # the iterator is self-iterable

上面的答案很好,但正如我所看到的,对于像我这样的人来说,不要过分强调区别

此外,人们倾向于“过于Pythonic”,将“X是一个具有
\uuu foo\uuu()
方法的对象”这样的定义放在前面。这样的定义是正确的——它们基于duck类型哲学,但是当试图以简单的方式理解概念时,对方法的关注往往介于两者之间

所以我添加了我的版本


在自然语言中

  • 迭代是在一行元素中一次获取一个元素的过程
在Python中

  • iterable是一个对象,是iterable,简而言之,意思是 它可以在迭代中使用,例如与
    for
    循环一起使用。怎么用?通过使用迭代器。 我将在下面解释

  • 。。。而迭代器是一个定义如何实际执行 迭代——特别是下一个元素是什么。这就是为什么它一定有
    next()
    方法

迭代器本身也是可迭代的,区别在于它们的
\uuuu iter\uuuu()
方法返回相同的对象(
self
),而不管其项是否已被先前对
next()
的调用使用


那么,当Python解释器在obj:
语句中看到x的
时,它会怎么想呢

L
class IterableExample(object):

    def __iter__(self):
        return self

    def next(self):
        pass
class Iterator(object):
    def next(self):
        pass

class Iterable(object):
    def __iter__(self):
        return Iterator()
class SmartIterableExample(object):

    def create_iterator(self):
        # An amazingly powerful yet simple way to create arbitrary
        # iterator, utilizing object state (or not, if you are fan
        # of functional), magic and nuclear waste--no kittens hurt.
        pass    # don't forget to add the next() method

    def __iter__(self):
        return self.create_iterator()
 >>> X = [1,2,3,4,5]
 >>> next(X)
 Traceback (most recent call last):
    File "<pyshell#19>", line 1, in <module>
      next(X)
 TypeError: 'list' object is not an iterator
>>> X = [1,2,3,4,5]
>>> bricks_kit = [1,2,3,4,5]
>>> white_piece_of_paper = iter(bricks_kit)
>>> next(white_piece_of_paper)
1
>>> next(white_piece_of_paper)
2
>>>
iterable = [1, 2] 

iterator = iter(iterable)

print(iterator.__next__())   

print(iterator.__next__())   
x=[1,2,3,4]
y=iter(x)
y=[1,2,3,4]
>>> y.next()
1
>>> y.next()
2
>>> y.next()
3
>>> y.next()
4
>>> y.next()
StopIteration
 sequence
  +
  |
  v
   def __getitem__(self, index: int):
  +    ...
  |    raise IndexError
  |
  |
  |              def __iter__(self):
  |             +     ...
  |             |     return <iterator>
  |             |
  |             |
  +--> or <-----+        def __next__(self):
       +        |       +    ...
       |        |       |    raise StopIteration
       v        |       |
    iterable    |       |
           +    |       |
           |    |       v
           |    +----> and +-------> iterator
           |                               ^
           v                               |
   iter(<iterable>) +----------------------+
                                           |
   def generator():                        |
  +    yield 1                             |
  |                 generator_expression +-+
  |                                        |
  +-> generator() +-> generator_iterator +-+
class Iterable1:
    def __iter__(self):
        # a method (which is a function defined inside a class body)
        # calling iter() converts iterable (tuple) to iterator
        return iter((1,2,3))

class Iterable2:
    def __iter__(self):
        # a generator
        for i in (1, 2, 3):
            yield i

class Iterable3:
    def __iter__(self):
        # with PEP 380 syntax
        yield from (1, 2, 3)

# passes
assert list(Iterable1()) == list(Iterable2()) == list(Iterable3()) == [1, 2, 3]
class MyIterable:

    def __init__(self):
        self.n = 0

    def __getitem__(self, index: int):
        return (1, 2, 3)[index]

    def __next__(self):
        n = self.n = self.n + 1
        if n > 3:
            raise StopIteration
        return n

# if you can iter it without raising a TypeError, then it's an iterable.
iter(MyIterable())

# but obviously `MyIterable()` is not an iterator since it does not have
# an `__iter__` method.
from collections.abc import Iterator
assert isinstance(MyIterable(), Iterator)  # AssertionError
>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    next(it)
StopIteration
class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]


>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
...     print(char)
...
m
a
p
s
In[2]: def my_generator():
  ...:     yield 100
  ...:     yield 200

In[3]: my_generator
Out[3]: <function __main__.my_generator()>
In[4]: type(my_generator)
Out[4]: function
In[5]: my_iterator = my_generator()
In[6]: my_iterator
Out[6]: <generator object my_generator at 0x00000000053EAE48>
In[7]: type(my_iterator)
Out[7]: generator
In[8]: my_gen_expression = (2 * i for i in (10, 20))
In[9]: my_gen_expression
Out[9]: <generator object <genexpr> at 0x000000000542C048>
In[10]: type(my_gen_expression)
Out[10]: generator
class Squares:
    def __init__(self, length):
        self.length = length
        self.i = 0
        
    def __iter__(self):
        print('calling __iter__') # this will be called first and only once
        return self
    
    def __next__(self): 
        print('calling __next__') # this will be called for each iteration
        if self.i >= self.length:
            raise StopIteration
        else:
            result = self.i ** 2
            self.i += 1
            return result
class Cities:
    def __init__(self):
        self._cities = ['Brooklyn', 'Manhattan', 'Prag', 'Madrid', 'London']
        self._index = 0
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self._index >= len(self._cities):
            raise StopIteration
        else:
            item = self._cities[self._index]
            self._index += 1
            return item
class Cities:
    def __init__(self):
        self._cities = ['New York', 'Newark', 'Istanbul', 'London']        
    def __len__(self):
        return len(self._cities)



class CityIterator:
    def __init__(self, city_obj):
        # cities is an instance of Cities
        self._city_obj = city_obj
        self._index = 0
        
    def __iter__(self):
        return self
    
    def __next__(self):
        if self._index >= len(self._city_obj):
            raise StopIteration
        else:
            item = self._city_obj._cities[self._index]
            self._index += 1
            return item
class Cities:
    def __init__(self):
        self._cities = ['New York', 'Newark', 'Istanbul', 'Paris']
        
    def __len__(self):
        return len(self._cities)
    
    def __iter__(self):
        return self.CityIterator(self)
    
    class CityIterator:
        def __init__(self, city_obj):
            self._city_obj = city_obj
            self._index = 0

        def __iter__(self):
            return self

        def __next__(self):
            if self._index >= len(self._city_obj):
                raise StopIteration
            else:
                item = self._city_obj._cities[self._index]
                self._index += 1
                return item
class Cities:
    def __init__(self):
        self._cities = ['New York', 'Newark', 'Budapest', 'Newcastle']
        
    def __len__(self):
        return len(self._cities)
    
    def __getitem__(self, s): # now a sequence type
        return self._cities[s]
    
    def __iter__(self):
        return self.CityIterator(self)
    
    class CityIterator:
        def __init__(self, city_obj):
            self._city_obj = city_obj
            self._index = 0

        def __iter__(self):
            return self

        def __next__(self):
            if self._index >= len(self._city_obj):
                raise StopIteration
            else:
                item = self._city_obj._cities[self._index]
                self._index += 1
                return item
    if(self.power<=self.max):
        result = 2**self.power
        self.power +=1
        return result

    else:
        raise StopIteration
ls = ['hello','bye']
print(dir(ls))
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']