程序员文章、书籍推荐和程序员创业信息与资源分享平台

网站首页 > 技术文章 正文

python散装笔记——32: 可迭代和迭代器

hfteth 2025-01-15 13:35:40 技术文章 18 ℃

1: 迭代器 vs 可迭代 vs 发生器

可迭代对象是可以返回迭代器的对象。任何有状态、有 __iter__方法并返回迭代器的对象都是可迭代对象。它也可以是实现了 __getitem__ 方法的无状态对象。- 该方法可以获取索引(从零开始),并在索引不再有效时引发一个 IndexError

Python 的 str 类就是一个 __getitem__ 可迭代器的例子。

迭代器是一个对象,当在某个对象上调用 next(*object*) 时,它会产生序列中的下一个值。此外,任何具有 __next__ 方法的对象都是一个迭代器。迭代器用完后会引发 StopIteration,此时不能再使用。

可迭代类

可迭代类定义了一个 __iter__ 方法和一个 __next__ 方法。可迭代类示例

class MyIterable:
  def __iter__(self):
    return self
  
  def __next__(self):
    #code
    
# Classic iterable object in older versions of python, __getitem__ is still supported...
class MySequence:
  def __getitem__(self, index):
    
    if (condition):
      raise IndexError
      return (item)
    
# Can produce a plain `iterator` instance by using iter(MySequence())

尝试实例化集合模块中的抽象类,以便更好地理解这一点。

示例

>>> import collections
>>> collections.Iterator()
TypeError: Cant instantiate abstract class Iterator with abstract methods __next__

通过以下操作在 Python 2 中处理可迭代类的 Python 3 兼容性:

Python 2.x Version ≥ 2.3

class MyIterable(object): #or collections.Iterator, which I'd recommend....
  ....
  def __iter__(self):
    return self
  
  def next(self): #code
    __next__ = next

这两个迭代器现在都可以循环使用:

ex1 = MyIterableClass()
ex2 = MySequence()
for (item) in (ex1): #code
for (item) in (ex2): #code

生成器是创建迭代器的简单方法。生成器是一个迭代器,而迭代器是一个可迭代器。

2: 逐一提取数值

从内置的 iter() 开始,在可迭代对象上获取迭代器,然后使用 next() 逐个获取元素,直到 停止迭代",表示迭代结束:

s = {1, 2} # or list or generator or even iterator
i = iter(s) # get iterator
a = next(i) # a = 1
b = next(i) # b = 2
c = next(i) # raises StopIteration

3: 对整个可迭代器进行迭代

s = {1, 2, 3}

# get every element in s
for a in s:
  print(a) # prints 1, then 2, then 3

# copy into list
l1 = list(s) # l1 = [1, 2, 3]

# use list comprehension
l2 = [a * 2 for a in s if a > 2] # l2 = [6]

4: 只验证可迭代元素中的一个元素

使用解包提取第一个元素,并确保它是唯一的元素:

# a, = iterable

def foo():
  yield 1

a, = foo() # a = 1

nums = [1, 2, 3]
a, = nums # ValueError: too many values to unpack

5: 可迭代的内容

Iterable 可以是只向前逐个接收项的任何东西。内置的 Python 集合都是可迭代的:

[1, 2, 3] # list, iterate over items
(1, 2, 3) # tuple
{1, 2, 3} # set
{1: 2, 3: 4} # dict, iterate over keys

生成器返回迭代表:

def foo(): # foo isn't iterable yet...
  yield 1
  
res = foo() # ...but res already is

6: 迭代器不是可重入的!

def gen():
  yield 1
  
iterable = gen()
for a in iterable:
  print(a)

# What was the first item of iterable? No way to get it now.
# Only to get a new iterator
gen()



Tags:

最近发表
标签列表