Python迭代器与生成器

目录

1.0 python推导式

1.1  什么是推导式?

1.1.1  列表推导式

1.1.2  集合推导式

1.1.3  字典推导式

2.0  python可迭代对象

2.1  什么是容器?

2.2  可迭代对象

2.2.1  判断一个对象是不是可迭代对象

3.0  迭代器(iterator)

3.1 编写迭代器,实现range

3.2 编写迭代器,实现斐波拉契数列

4.0 生成器(generator)

4.1 什么是生成器?

4.2 生成器表达式


1.0 python推导式

1.1  什么是推导式?

推导式comprehensions(又称解析式),是Python的一种独有特性。推导式是可以从一
个数据序列构建另一个新的数据序列的结构体。
共有三种推导,在Python2和3中都有支持:

1.1.1  列表推导式

列表(list)推导式   ---》用 [] 生成list
基本格式:variable = [out_exp_res for out_exp in input_list if out_exp == 2]
out_exp_res : 列表生成元素表达式,可以是有返回值的函数。
for out_exp in input_list : 迭代input_list将out_exp传入out_exp_res表达式中。
if out_exp == 2 : 根据条件过滤哪些值
示例:打印20以内不是3的倍数的数的平方
方法1:
tmp = []
for i in range(20):
    if i % 3:
        tmp.append(i*i)
print(tmp)

E:\python\python3.9.1\python.exe E:/tlbb/2022-07-08-迭代器与生成器/01.推导式.py
[1, 4, 16, 25, 49, 64, 100, 121, 169, 196, 256, 289, 361]
[1, 4, 16, 25, 49, 64, 100, 121, 169, 196, 256, 289, 361]

Process finished with exit code 0

列表推导式写法:

result = [ i*i for i in range(20) if i % 3 ]
print(result)

E:\python\python3.9.1\python.exe E:/tlbb/2022-07-08-迭代器与生成器/01.推导式.py
[1, 4, 16, 25, 49, 64, 100, 121, 169, 196, 256, 289, 361]

Process finished with exit code 0
示例:使用列表推导式输出200以内,开平方是整数的数
result = [i for i in range(200) if math.sqrt(i).is_integer()]
print(result)

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196]

示例:将列表里的小数保留两位小数输出到列表

lst1 = [2.45345, 4.3454325, 9, 82.234321, 83.841234]
lst2 = [float("%0.2f" % j) for j in lst1 if j]
print(lst2)

['2.45', '4.35', '9.00', '82.23', '83.84']

示例:找到嵌套列表中名字含有2个'e'的所有名字

names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
         ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva', 'Elven']]

方法1:

for i in names:
    for j in i:
        if j.lower().count('e') >= 2:
            print(j)

Jefferson
Wesley
Steven
Jennifer
Elven

列表推导式:

result1 = [j for i in names for j in i if j.lower().count('e') >= 2]
print(result1)

['Jefferson', 'Wesley', 'Steven', 'Jennifer', 'Elven']

#################################

1.1.2  集合推导式

因为集合的特性,集合推导式自带去重功能。

# 集合推导式 --》 天生去重
str1 = "qwerqwerasasfdfd"
print(set(str1))
print({i for i in str1})

E:\python\python3.9.1\python.exe E:/tlbb/2022-07-08-迭代器与生成器/01.推导式.py
{'e', 'f', 'q', 'd', 'a', 'w', 's', 'r'}
{'e', 'f', 'q', 'd', 'a', 'w', 's', 'r'}

#################################

’1.1.3  字典推导式

字典(dict)推导式
字典推导和列表推导的使用方法是类似的,只不中括号该改成大括号。
基本格式:variable = {out_key:out_value for out_key,out_value in input_list if out_exp == 2}
out_key: 返回字典结果的key
out_value: 返回字典结果的value
for out_key,out_value in input_list: 迭代input_list将out_exp传入out_exp_res表达式中。
if out_exp == 2: 根据条件过滤哪些值可以。
示例:
# 字典推导式
print({x: y for x, y in [('a', 1), ('b', 2)]})
# 统计字符串中每一个字符出现的字数
str1 = "aleiafesl5e-e;'ree2f5a43"
print({x: str1.count(x) for x in str1})
# 过滤长度小于三的字符串,并将剩下的转换成大写字母
q1 = ['a', 'ab', 'abc', 'abcd', 'abcde']
print([i.upper() for i in q1 if len(i) >= 3])
# 求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数组成的元组列表
result = [(x, y) for x in range(6) for y in range(6) if x % 2 == 0 and y % 2 ==1]
print(result)
# 快速跟换key和value
q3 = {'a': 10, 'b': 34}
print({q3[x]: x for x in q3})
# 合并大小写对应的value值,将key统一写成小写
q4 = {'B': 3, 'a': 1, 'b': 6, 'c': 3, 'A': 4}
result2 = {x.lower(): q4.get(x.lower(), 0) + q4.get(x.upper(), 0) for x, y in q4.items()}
print(result2)

str1 = "aleiafesl5e-e;'ree2f5a43"
tmp = {}
for i in str1:
    tmp[i] = tmp.get(i, 0) + 1
print(tmp)



E:\python\python3.9.1\python.exe E:/tlbb/2022-07-08-迭代器与生成器/01.推导式.py
{'a': 1, 'b': 2}
{'a': 3, 'l': 2, 'e': 6, 'i': 1, 'f': 2, 's': 1, '5': 2, '-': 1, ';': 1, "'": 1, 'r': 1, '2': 1, '4': 1, '3': 1}
['ABC', 'ABCD', 'ABCDE']
[(0, 1), (0, 3), (0, 5), (2, 1), (2, 3), (2, 5), (4, 1), (4, 3), (4, 5)]
{10: 'a', 34: 'b'}
{'b': 9, 'a': 5, 'c': 3}
{'a': 3, 'l': 2, 'e': 6, 'i': 1, 'f': 2, 's': 1, '5': 2, '-': 1, ';': 1, "'": 1, 'r': 1, '2': 1, '4': 1, '3': 1}

Process finished with exit code 0

#################################

2.0  python可迭代对象

之前只学习了一部分内容的时候说过,可以for循环的都属可迭代对象,那么有哪些常见可迭代对象?

list, set, dict,tuple,str,file等这些都属容器数据结构

#################################

2.1  什么是容器?:

容器(container)
容器是一种 把多个元素组织在一起 的数据结构,容器中的元素 可以逐个地迭代获取 ,可以用 in, not
in关键字判断 元素是否包含在容器中。
通常这类数据结构把所有的元素存储在内存中(也有一些特例,并不是所有的元素都放在内存,比如
迭代器和生成器对象)

#################################

2.2  可迭代对象

什么是可迭代对象?
凡是实现了__iter__方法,并且可以返回一个迭代器的对象都可以称之为可迭代对象。
str1 = "abc"
# 一般来说容器类型都是可迭代对象
print(dir(str1))


E:\python\python3.9.1\python.exe E:/tlbb/2022-07-08-迭代器与生成器/02.迭代器和生成器.py
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
print(hasattr(str1, "__iter__"))

True
一般来说,容器类型的数据结构都是可迭代对象。
例:这里有一个类 A,它有__iter__方法,但是没有返回迭代器,所以它不是可迭代对象
class A:
    def __iter__(self):
        return None

#################################

2.2.1  判断一个对象是不是可迭代对象

使用iterable判断

from collections import Iterable
a='abc'
b = [1,2,3]
c=(4,5,6)
d={"name": 'tom', "age": 22}
if isinstance(a, Iterable):
    print("a是可迭代对象")
if isinstance(b, Iterable):
    print("b是可迭代对象")

E:\python\python3.9.1\python.exe E:/tlbb/2022-07-08-迭代器与生成器/01.推导式.py
a是可迭代对象
b是可迭代对象

#################################

3.0  迭代器(iterator)

什么是迭代器?
迭代器是 有状态的 ,可以被next()调用,函数调用并不断返回下一 个值的对象称为迭代(Iterator)。

 任何实现了__iter__()和__next__()都是迭代器

__iter__():返回迭代器自身
__next__():返回容器中的下一个值
如果容器中没有更多元素了,则抛出 StopIteration 异常
(for循环取数据遇到StopIteration时,会退出循环)
所有的Iterable均可以通过内置函数iter()来转变为Iterator。
#################################

3.1 编写迭代器,实现range

class Myrange():
    def __init__(self, num):
        self.num = num
        self.start = 0

    def __iter__(self):
        self.cur_val = self.start - 1
        return self

    def __next__(self):
        self.cur_val += 1
        if self.cur_val < self.num:
            return self.cur_val
        else:
            raise StopIteration


for i in Myrange(10):
    print(i)
E:\python\python3.9.1\python.exe E:/tlbb/2022-07-08-迭代器与生成器/02.迭代器和生成器.py
0
1
2
3
4
5
6
7
8
9

#################################

3.2 编写迭代器,实现斐波拉契数列

class Fblq():
    n = 0
    def __init__(self, num):
        self.num = num
        self.next = 0
        self.start = 1
        self.middle = 1

    def __iter__(self):
        return self

    def __next__(self):
        self.n += 1
        if self.n == 1 or self.n == 2:
            return self.middle
        if self.next <= self.num:
            self.next = self.start + self.middle
            self.middle = self.start
            self.start = self.next
            return self.next
        else:
            raise StopIteration

for i in Fblq(6):
    print(i)
E:\python\python3.9.1\python.exe E:/tlbb/2022-07-08-迭代器与生成器/02.迭代器和生成器.py
1
1
2
3
5
8

#################################

4.0 生成器(generator)

4.1 什么是生成器?

生成器算得上是Python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,
不过这种迭代器更加优雅。它不需要手动编写__iter__()和__next__()方法,只需要一个
yiled关键字。
生成器一定是迭代器(反之不成立)
因此任何生成器也是以一种懒加载的模式生成值(惰性求值)
#################################

4.2 生成器表达式

 生成器表达式
使用()生成generator,
将俩表推导式的[]改成()即可得到生成器。
列表推导式与生成器表达式,定义和使用非常类似,但是,在(大量数据处理时)性能上相
差很大
yield关键字
包含yield表达式的函数是特殊的函数,叫做 生成器函数(generator function) ,被调用时将返回一个
迭代器(iterator),调用时可以使用next或send(msg)
一个生成器中可以有多个yield
一旦遇到yield,就会保存当前状态,然后返回yield后面的值
def get_content():
    print("start yield...")
    yield 3
    print("second yield")
    yield 4
    print("end...")

g1 = get_content()
print(dir(g1))
print('*'*20)
print(next(g1))
print('*'*20)
print(next(g1))
print('*'*20)
print(next(g1))
********************
start yield...
3
********************
second yield
4
********************
end...
Traceback (most recent call last):
  File "E:\tlbb\2022-07-08-迭代器与生成器\02.迭代器和生成器.py", line 115, in <module>
    print(next(g1))
StopIteration

Process finished with exit code 1

使用生成器编写range

def Myrange(num):
    i = 0
    while i < num:
        yield i
        i += 1
for i in Myrange(3):
    print(i)
E:\python\python3.9.1\python.exe E:/tlbb/2022-07-08-迭代器与生成器/02.迭代器和生成器.py
0
1
2

Process finished with exit code 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值