商城网站建设公司排行,专业做调查的网站,wordpress 中文链接,wordpress cross apple一、迭代器
1.1、什么是迭代
迭代是指反复的执行一个过程#xff0c;每次执行都会根据前一次的结果进行调整和优化。在计算机编程中#xff0c;迭代常常用于循环执行某个操作#xff0c;直到达到特定的条件或达成目标。迭代也可以用于指代软件开发中的“迭代开发”#x…一、迭代器
1.1、什么是迭代
迭代是指反复的执行一个过程每次执行都会根据前一次的结果进行调整和优化。在计算机编程中迭代常常用于循环执行某个操作直到达到特定的条件或达成目标。迭代也可以用于指代软件开发中的“迭代开发”即将一个大型软件开发项目分成多个小的迭代周期每个迭代周期都完成一个可用的软件产品版本以便及时反馈和调整。迭代的目的是不断优化和改进逐步达成更好的结果。
1.2、什么是迭代器
迭代器Iterator是一种设计模式它提供了一种访问集合Collection中元素的方法而不必暴露集合内部实现的细节。迭代器为不同类型的集合提供了一种统一的遍历方式使得集合的迭代访问变得更加简单和方便。迭代器通过提供 hasNext() 和 next() 等方法来实现集合的迭代访问。hasNext() 方法用于判断集合是否还有下一个元素next() 方法用于返回集合中的下一个元素。迭代器还可以提供 remove() 方法来删除集合中的元素。
1.3、Python 中的可迭代对象
在Python中可迭代对象是指实现了__iter__()方法的对象该方法返回一个迭代器Iterator对象。以下是一些常见的Python中的可迭代对象
列表List列表是最常用的可迭代对象之一可以使用for循环遍历列表中的元素。元组Tuple与列表类似元组也是可迭代对象可以通过for循环遍历其中的元素。字符串String字符串也是可迭代对象可以将字符串中的每个字符作为迭代器返回。集合Set集合也是可迭代对象可以使用for循环遍历集合中的元素。字典Dictionary字典在迭代时默认遍历的是字典的键。可以使用items()方法遍历字典的键值对。文件对象File Object文件对象也是可迭代对象可以按行迭代读取文件内容。生成器Generator生成器是一种特殊的可迭代对象可以通过yield语句生成迭代器。
除了以上常见的可迭代对象还可以自定义类实现__iter__()方法使其成为可迭代对象。通过实现__iter__()方法可以定义自己的迭代器行为从而实现自定义的迭代逻辑。
使用isinstance和Iterable判断对象是否可迭代
from collections import Iterableprint isinstance([], Iterable) # Trueprint isinstance((), Iterable) # Trueprint isinstance(nihao, Iterable) # Trueprint isinstance({1, 2, 3}, Iterable) # Trueprint isinstance({name: liqiang}, Iterable) # Truewith open(xxx.py, r) as f:print isinstance(f, Iterable) # Truen (x*3 for x in range(4))
print n # generator object genexpr at 0x106fda410
print isinstance(n, Iterable) # Trueprint isinstance(a, Iterable) # Trueprint isinstance(100, Iterable) # False1.4、Python 中生成迭代器的方法
1.4.1、iter()函数
该方法返回迭代器对象本身self
L [1, 5, 6]
t (1, 5, 6)
s nihao
set1 {1, 5, 6}
d {name: liqiang}liter iter(L)
titer iter(t)
siter iter(s)
setiter iter(set1)
diter iter(d)print liter.next() # 1
print titer.next() # 1
print titer.next() # 5
print siter.next() # n
print setiter.next() # 1
print diter.next() # name
print liter.next() # 5
print diter.next() # 如果没有下一个元素则抛出StopIteration异常
Traceback (most recent call last):File xxx.py, line 44, in moduleprint diter.next()
StopIteration1.4.2、enumerate()函数
该函数返回一个迭代器对象包含传入可迭代对象的索引和元素。enumerate()函数是python的内置函数用于将一个可遍历的数据对象如列表、元组、字符串组合为一个索引序列同时列出数据和数据下标。它返回一个枚举对象包含了索引和对应的数据。使用方法如下
enumerate(iterable, start0)其中iterable是一个可迭代对象start是可选参数用于设置起始的索引默认为0。 示例如下
name_list [zhangsan, lisi, wangwu]
for index, name in enumerate(name_list):print(index, name)
print -----------------------------------
iter_object enumerate(name_list)
print iter_object.next()
print iter_object.next()
print iter_object.next()
print iter_object.next()# 结果如下
(0, zhangsan)
(1, lisi)
(2, wangwu)
-----------------------------------
(0, zhangsan)
(1, lisi)
(2, wangwu)
Traceback (most recent call last):File /Users/gaoyueyun/Documents/code/文件操作/python-test/可迭代对象.py, line 54, in moduleprint iter_object.next()
StopIteration1.4.3、zip()函数
zip()函数是python的内置函数用于将多个可迭代对象合并成一个元组序列常用于将多个列表、元组或其他可迭代对象中的对应元素进行配对。使用方法如下
zip(*iterables)*iterables表示一个或多个可迭代对象可以是列表、元组、字符串、集合等。zip()函数将这些可迭代对象中的对应元素组合成为一个元组序列返回一个zip对象可以通过iter()函数将其转换为迭代器。
names_list [zhangsan, lisi, wangwu]
ages_list [20, 25, 30]
heights_list [1.6, 1.8, 1.7]for name, age, height in zip(names_list, ages_list, heights_list):print(name, age, height)
print -----------------------------------
iter_object zip(names_list, ages_list, heights_list)
print iter_object.next()
print -----------------------------------
iter_object iter(zip(names_list, ages_list, heights_list))
print iter_object.next()
print iter_object.next()
print iter_object.next()# 结果如下
(zhangsan, 20, 1.6)
(lisi, 25, 1.8)
(wangwu, 30, 1.7)
-----------------------------------
Traceback (most recent call last):File /Users/gaoyueyun/Documents/code/文件操作/python-test/可迭代对象.py, line 54, in moduleprint iter_object.next()
AttributeError: list object has no attribute next
-----------------------------------
(zhangsan, 20, 1.6)
(lisi, 25, 1.8)
(wangwu, 30, 1.7)1.4.4、map()函数
map()函数是python的内置函数用于对一个或多个可迭代对象中的元素逐个应用某个函数返回一个迭代器。使用方法如下
map(function, *iterables)function是一个函数对象*iterables表示一个或多个可迭代对象可以是列表、元组、字符串、集合等。map()函数将function应用于iterables中的元素逐个返回结果。示例如下
def square(x):return x ** 2numbers [1, 2, 3, 4, 5]
squared_numbers map(square, numbers)print(squared_numbers)
print ----------------------------------
squared_numbers iter(map(square, numbers))
print squared_numbers.next()
print squared_numbers.next()
print squared_numbers.next()
print squared_numbers.next()# 结果如下
[1, 4, 9, 16, 25]
----------------------------------
1
4
9
161.4.5、filter()函数
filter()函数是python的内置函数用于过滤一个可迭代对象中的元素返回一个迭代器。使用方法如下
filter(function, iterable)function是一个用于过滤元素的函数对象iterable是一个可迭代对象可以是列表、元组、字符串、集合等。filter()函数将function应用于iterable中的每个元素返回一个只包含满足条件的元素的迭代器。示例如下
num_list [1, 2, 3, 4, 5]
filter_object iter(filter(lambda x: x 2, num_list))
print filter_object.next()
print filter_object.next()
print filter_object.next()def get_num(x):if x 2:return xfilter_object filter(get_num, num_list)
print filter_object
filter_object iter(filter(get_num, num_list))
print filter_object.next()
print filter_object.next()
print filter_object.next()# 结果如下
3
4
5
[3, 4, 5]
3
4
51.4.6、reversed()函数
reversed()函数是python的内置函数用于反转一个序列如列表、元组、字符串的元素顺序返回一个迭代器。使用方法如下
reversed(sequence)sequence是一个序列可以是列表、元组、字符串等。reversed()函数将sequence中的元素顺序进行反转返回一个迭代器。示例如下
num_list [1, 2, 3, 4, 5]
re_object reversed(num_list)
print re_object.next()
print re_object.next()
print re_object.next()
print re_object.next()
print re_object.next()# 结果如下
5
4
3
2
11.4.7、sorted()函数
sorted()函数是python的内置函数用于对一个序列如列表、元组、字符串进行排序返回一个新的已排序的列表。使用方法如下
sorted(iterable, keyNone, reverseFalse)iterable是一个序列可以是列表、元组、字符串等key是一个函数用于指定排序规则默认为None表示按照元素的大小比较进行排序reverse是一个布尔值用于指定是否降序排列默认为False表示升序排列。示例如下
num_list [6, 0, 7, 3, 9, 12]
s_object sorted(num_list)
print s_object
print ------------------------------
s2_object iter(sorted(num_list, reverseTrue))
print s2_object
print s2_object.next()
print s2_object.next()
print s2_object.next()
print s2_object.next()
print s2_object.next()
print s2_object.next()# 结果如下
[0, 3, 6, 7, 9, 12]
------------------------------
listiterator object at 0x106a6e150
12
9
7
6
3
01.5、自定义迭代器类
自定义迭代器类需要实现__iter__()和__next__()两个方法。iter()方法返回迭代器本身next()方法用于返回容器中的下一个值。例如
class MyIterator:def __init__(self, container):self.container containerself.index 0def __iter__(self):return selfdef __next__(self):if self.index len(self.container):raise StopIterationvalue self.container[self.index]self.index 1return valueiter01 MyIterator([1, 2, 3])
print iter01.__next__()
print iter01.__next__()
print iter01.__next__()# 结果如下
1
2
31.6、迭代器和列表的区别 存储方式列表是一种数据结构以连续的内存空间来存储元素可以随机访问其中的任意元素。而迭代器是一种访问集合中元素的方式可以一次访问一个元素而不需要提前加载所有元素到内存中。 内存占用列表将所有元素一次性加载到内存中占用的内存空间较大。而迭代器仅在需要时生成和返回元素占用的内存空间较小。 访问方式列表可以通过索引来直接访问和修改元素。而迭代器需要逐个调用next()方法来访问和返回元素。 遍历次数列表可以被多次遍历每次遍历都是从头开始。而迭代器只能遍历一次遍历结束后需要重新创建迭代器对象才能再次遍历。 惰性计算迭代器可以进行惰性计算即在需要时才生成下一个元素可以节省计算资源。而列表在创建时就会立即计算和存储所有元素。
迭代器是一种按需生成和访问元素的方式适用于处理大量数据或无需提前加载所有数据的场景。列表是一种数据结构适用于需要随机访问元素或多次遍历的场景。
迭代器Iterator和可迭代对象Iterable区别 接口实现可迭代对象是指实现了__iter__()方法的对象该方法返回一个迭代器对象。而迭代器是指实现了__iter__()和__next__()方法的对象其中__iter__()方法返回迭代器对象本身next()方法用于返回容器中的下一个值。 访问方式可迭代对象可以通过for循环直接进行遍历也可以通过iter()函数将其转换为迭代器。迭代器需要使用next()函数或者for循环来逐个访问元素。 存储方式可迭代对象可以是一次性将所有元素存储在内存中的数据结构例如列表、元组、集合等。迭代器是一种按需生成和返回元素的机制可以节省内存空间特别适用于处理大量数据或无需提前加载所有数据的情况。 遍历次数可迭代对象可以被多次遍历每次遍历都是从头开始。而迭代器只能遍历一次遍历结束后需要重新创建迭代器对象才能再次遍历。 惰性计算迭代器可以进行惰性计算即在需要时才生成下一个元素可以节省计算资源。可迭代对象在创建时就会立即计算和存储所有元素。
可迭代对象是一种具有遍历能力的对象它可以通过迭代器来进行遍历。迭代器是一种按需生成和访问元素的机制用于遍历可迭代对象。迭代器相对于可迭代对象更加灵活和节省内存适用于处理大量数据或需要惰性计算的场景。因此在Python中使用迭代器可以提高程序的效率和性能。
1.7、迭代器和for循环区别 实现方式迭代器是基于迭代器协议实现的需要自定义__iter__()和__next__()方法。而for循环是Python提供的一种高级语法用于遍历可迭代对象。 访问方式使用迭代器时需要通过调用next()函数或者使用for循环来逐个访问元素。而for循环直接使用可迭代对象进行遍历无需关心迭代器的具体实现。 遍历方式迭代器逐个返回元素可以按需生成和返回元素即使处理大量数据也不需要提前加载所有数据到内存中。而for循环会一次性将所有元素加载到内存中然后按顺序进行遍历。 遍历次数迭代器只能遍历一次遍历结束后需要重新创建迭代器对象才能再次遍历。而for循环可以多次遍历可迭代对象每次都是从头开始遍历。 使用场景迭代器适用于处理大量数据或无需提前加载所有数据的情况可以节省内存空间。for循环适用于一次性遍历所有元素并且无需关心具体的迭代实现。
迭代器是一种按需生成和访问元素的机制适用于处理大量数据或需要惰性计算的场景。而for循环是一种便捷的语法适用于遍历可迭代对象无需关心其具体的迭代实现。
二、生成器
2.1、什么是生成器
在 Python 中使用了yield的函数被称为生成器generator。yield是一个关键字用于定义生成器函数生成器函数是一种特殊的函数可以在迭代过程中逐步产生值而不是一次性返回所有结果。跟普通函数不同的是生成器是一个返回迭代器的函数只能用于迭代操作更简单点理解生成器就是一个迭代器。当在生成器函数中使用yield语句时函数的执行将会暂停并将yield后面的表达式作为当前迭代的值返回。然后每次调用生成器的next()方法或使用for循环进行迭代时函数会从上次暂停的地方继续执行直到再次遇到yield语句。这样生成器函数可以逐步产生值而不需要一次性计算并返回所有结果。调用一个生成器函数返回的是一个迭代器对象。
2.2、创建生成器
2.2.1、生成器表达式
生成器表达式是一种类似于列表推导式的语法但是生成的是一个生成器对象。使用生成器表达式时不需要显式定义函数直接在一对圆括号内编写表达式即可。示例如下
gen (x for x in range(0, 4))
print gen.next()
print(next(gen))
print(next(gen))
print gen.next()print -------------------------list_method [x for x in range(0, 4)]
print next(list_method)
print list_method.next()# 结果如下
0
1
2
3
-------------------------
Traceback (most recent call last):File /Users/gaoyueyun/Documents/code/文件操作/python-test/可迭代对象.py, line 151, in moduleprint next(list_method)
TypeError: list object is not an iterator2.2.2、生成器函数
生成器函数是一种特殊的函数其中包含yield语句。当调用生成器函数时并不会执行函数体内的代码而是返回一个生成器对象。每次调用生成器的__next__()方法时会执行生成器函数体内的代码直到遇到yield语句将yield后面的表达式作为生成器的返回值并暂停执行函数。下次调用__next__()方法时会从上次暂停的位置继续执行。示例如下
def countdown(n):while n 0:yield nn - 1# 创建生成器对象
generator countdown(5)# 通过迭代生成器获取值
print(next(generator)) # 输出: 5
print(next(generator)) # 输出: 4
print(next(generator)) # 输出: 3# 使用 for 循环迭代生成器
for value in generator:print(value) # 输出: 2 12.3、生成器常用方法
2.3.1、send(value)
向生成器发送一个值并继续生成器的执行。该方法的作用类似于yield表达式可以将一个值发送给生成器并让生成器继续执行。使用该方法时需要先调用一次next()方法使生成器运行到yield语句的位置。示例如下
def my_generator():while True:value yieldprint(value)gen my_generator()
next(gen) # 运行到 yield 语句
gen.send(1) # 输出1
gen.send(2) # 输出2使用send(value)方法时需要注意以下几点 在第一次调用生成器对象之前需要先使用一次next()方法使生成器执行到yield语句的位置。 生成器对象的send(value)方法会将value赋值给yield表达式左边的变量并继续执行生成器直到遇到下一个yield表达式或结束。 首次调用send(value)方法时传递的参数值会被忽略即不会赋值给第一个yield表达式的左边变量。如果非要给第一个yield表达式传递一个初始值可以通过先调用next()方法然后使用send(value)方法。
在上述示例中首先调用next(gen)将生成器执行到第一个yield语句的位置。然后gen.send(1)将值1发送给生成器赋值给yield表达式左边的变量value并继续执行生成器打印出1。接着gen.send(2)再次发送值2给生成器赋值给value并打印出2。
通过使用send(value)方法我们可以在生成器的执行过程中提供不同的输入值并根据需要进行后续的处理。
2.3.2、close()
关闭生成器。调用该方法后生成器将无法再次使用。
def countdown(n):while n 0:yield nn - 1# 创建生成器对象
generator countdown(5)# 通过迭代生成器获取值
print(next(generator)) # 输出: 5
generator.close() # 关闭生成器
print(next(generator)) # 抛出StopIteration异常2.3.3、throw()
向生成器抛出一个异常。使用该方法时需要先调用一次next()方法使生成器运行到yield语句的位置。示例如下
def countdown(n):while n 0:try:yield nn - 1except ValueError:print 报错了# 创建生成器对象
generator countdown(5)# 通过迭代生成器获取值
print(next(generator)) # 输出: 5
print(next(generator)) # 输出: 4
generator.throw(ValueError) # 输出: 报错了
print(next(generator)) # 输出: 3
print(next(generator)) # 输出: 2
print(next(generator)) # 输出: 12.3.3、yield from
将一个可迭代对象委托给生成器。使用该语法可以简化生成器的实现使其更加清晰和易读。需要说明的是python2不支持python3.3以后支持。示例如下
def countdown(n):while n 0:yield nn - 1def my_gen(n):yield from countdown(n)yield n1# 创建生成器对象
generator my_gen(5)print(generator)
print(list(generator)) # [5, 4, 3, 2, 1, 6]# 通过迭代生成器获取值
print(next(generator))generator object my_gen at 0x10856f270
[5, 4, 3, 2, 1, 6]
Traceback (most recent call last):File xxx.py, line 167, in moduleprint(next(generator))
StopIteration2.4、yield和yield from 区别
yield原理
yield用于定义生成器函数包含yield语句的函数。当生成器函数被调用时它会返回一个生成器对象而不是立即执行函数体。在生成器函数中yield语句将生成一个值并将生成器的状态暂停保存当前的上下文环境并返回值给调用者。调用生成器的__next__()方法或使用for循环迭代生成器时会恢复生成器的状态继续执行后续的代码。yield语句可以出现在函数中的任意位置并且可以出现多次。
yield from原理
yield from语句用于在生成器函数内部的控制权委派另一个生成器或可迭代对象进行迭代。当使用yield from委派给子生成器时子生成器将负责产生值并将这些值返回给yield from的调用者。同时yield from还可以传递给子生成器发送的值。yield from会自动处理委派生成器和子生成器之间的异常传递使得异常能够正确地向上层传递。yield from可以用于多层嵌套将委派生成器和子生成器层层连接起来。
yield是一个表达式它可以将值传递给调用方并暂停函数的执行。当再次调用函数时函数会从暂停的位置继续执行直到遇到下一个yield。yield实际上是生成器函数的核心机制它允许生成器函数产生多个值并且在每次产生值后可以暂停执行。
yield from是Python3.3中引入的新特性它可以将另一个生成器或可迭代对象委托给当前生成器来生成。使用yield from委托生成器时有两种情况 如果委托的是生成器那么委托生成器会完全接管当前生成器的控制权直到委托生成器返回或抛出异常。 如果委托的是可迭代对象那么yield from会自动处理迭代器和异常直到可迭代对象耗尽或抛出异常。yield from语句将返回可迭代对象生成的所有值。
从原理上来说yield from的实现比yield复杂得多。yield from实际上是一个语法糖它隐藏了生成器和迭代器之间的所有细节。当使用yield from语句时Python会自动处理所有的迭代器和生成器协议。具体来说Python会自动创建一个子生成器对象并在子生成器完成时自动捕获并处理所有的StopIteration异常。
举个例子考虑以下代码
list01 [0, 1, 2, 3, 4]def g1():yield list01def g2():yield from list01it1 g1()
it2 g2()for x in it1:print(x)for x in it2:print(x)# 结果如下
[0, 1, 2, 3, 4]
0
1
2
3
4yield from相比yield优势
yield from语句可以将嵌套的可迭代对象“展开”使得代码更简洁而不需要显式地写出循环语句。yield from语句可以简化异常处理当嵌套的可迭代对象中发生异常时它会自动传播到生成器中并被捕获和处理。yield from语句可以将生成器的控制权交给其他生成器或协程以实现更灵活的协作式并发编程。yield from语句在处理过程中会自动处理子生成器返回的值和异常而yield语句需要手动处理。
2.5、迭代器和生成器的异同
共同点
迭代器和生成器都是用于实现迭代行为的工具用于遍历序列中的元素或处理大量数据。迭代器和生成器都是惰性计算的即只在需要时才产生值。迭代器和生成器都可以实现无限序列的处理因为它们是按需生成值的。
区别
迭代器是任何实现了__iter__()和__next__()方法的对象它是一个迭代器协议的实现。而生成器是一种特殊的迭代器它是通过生成器函数或生成器表达式创建的。生成器是一种更加高级、更加方便的实现迭代行为的方式它使用yield关键字逐步产生值并在每次产生值后暂停执行等待下一次迭代。迭代器则需要显式地实现__next__()方法来产生值。生成器可以通过生成器函数或生成器表达式来创建而迭代器则可以是任何实现了__iter__()和__next__()方法的对象例如列表、元组、字符串等。
2.6、语法糖
语法糖Syntactic sugar是指编程语言中的一种语法构造它可以使代码更简洁、易读和易写但实际上并没有提供任何新的功能。语法糖是对底层语言特性的高级封装使得编码变得更加方便和直观。
语法糖通常是一种编译器或解释器的功能它可以将简洁的高级语法转换为底层的更复杂的语法结构。 这样做的目的是为了提高代码的可读性和可维护性以及减少程序员编写错误的可能性。
语法糖可以包括各种形式的简化语法如简洁的表达式、简化的控制结构或简化的数据类型定义。它们通常不是必需的可以通过使用底层语言特性来实现相同的功能但语法糖可以大大简化代码的编写和理解。
常见的语法糖包括简化的迭代器和循环结构、自动类型推导、操作符重载、匿名函数和Lambda表达式等。这些语法糖使得代码更加简洁、易读和易写但实际上它们都是通过编译器或解释器在底层进行转换和处理的。
python 常见语法糖 列表推导式用一行代码快速生成列表例如 [x for x in range(10)] 可以生成一个包含0到9的列表。 字典推导式类似于列表推导式用一行代码快速生成字典例如 {x: x**2 for x in range(10)} 可以生成一个键为0到9的数字对应值为它们的平方的字典。 带有if条件的推导式在列表推导式或字典推导式中加入if条件可以根据条件过滤元素或进行条件赋值。例如 [x for x in range(10) if x % 2 0] 可以生成一个包含0到9中偶数的列表。 装饰器装饰器是一种用于修改或增强函数功能的语法糖。通过在函数定义前使用符号和装饰器函数可以简化函数的装饰过程。 上下文管理器通过with语句和__enter__、__exit__方法可以简化对资源的管理例如文件的打开和关闭。
2.7、yield 实现斐波那契数列
斐波那契数列Fibonacci sequence又称黄金分割数列、因数学家列昂纳多·斐波那契Leonardoda Fibonacci以兔子繁殖为例子而引入故又称为“兔子数列”。
指的是这样一个数列1、1、2、3、5、8、13、21、34、……在数学上斐波纳契数列以如下被以递推的方法定义F(1)1F(2)1, F(n)F(n-1)F(n-2)
def fibonacci(n):斐波那契数列实现a, b 0, 1while n 0:a, b b, a bn - 1yield a# 另一种写法
def fibonacci(n): # 生成器函数 - 斐波那契a, b, counter 0, 1, 0while True:if (counter n): returnyield aa, b b, a bcounter 1# 获取斐波那契数列前 10 个成员
fibonacci_ fibonacci(10)
for i in fibonacci_:print(i)# 结果如下
1
1
2
3
5
8
13
21
34
55三、参考文档
1、https://www.yisu.com/zixun/312592.html
2、https://blog.csdn.net/qq_36441027/article/details/105919241
3、https://www.cnblogs.com/chengxuyuanaa/p/13065794.html
4、https://www.cnblogs.com/jiba/p/14047159.html
5、https://my.oschina.net/u/4330317/blog/4202095
6、https://www.cnblogs.com/alex3714/articles/5765046.html
7、https://kelepython.readthedocs.io/zh/latest/c01/c01_11.html