0
点赞
收藏
分享

微信扫一扫

python高阶编程(一)推导式,迭代器,生成器

墨春 2022-05-02 阅读 52
python

1、推导式

Python 推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体。推导式的优势:代码简洁,快速生成对应数据,且内存占用小

Python 支持各种数据结构的推导式:

  • 列表(list)推导式
  • 字典(dict)推导式
  • 集合(set)推导式
  • 元组(tuple)推导式

1、列表推导式

普通的方法生成list:

list = []

for  i in range(100):
    list.append(i)

print(list)

使用推导式:

表达式:[x for x in xx]

list = [i for i in range(100)]
print(list)

推导式加上if判断

表达式:[x for x in xx if 条件]

list = [i for i in rang(100) if i%2==0]
print(list)

推导式加上if--else

表达式:[x if 条件 else 条件 for x in xx]

list3 = ['{}偶数'.format(i) if i%2==0 else '{}奇数'.format(i) for i in range(100)]
print(list3)

2、字典推导式

普通方法生成字典:

list = ['a','b','c','d','e','f','g']

dict = {}

for i,j in  enumerate(li):
    dict1[i]=j
print(dict1)

使用推导式:

表达式:{x:j for x,j in xj}

dict2 = {i:j for i,j in enumerate(li)}
print(dict2)

3、集合推导式

集合推导式和列表推导式基本 一样,只是将[]替换成{}

set = {i for i in range(100)}
print(set)

4、元组推导式/生成器表达式

元组推导式可以利用 range 区间、元组、列表、字典和集合等数据类型,快速生成一个满足指定需求的元组。元组推导式它有一个特殊的名字,叫生成器表达式

生成器:

gen = (i for i in range(10))
print(gen)

>>><generator object <genexpr> at 0x000001EC11153C80>

generator object,就是一个生成器对象

2、可迭代对象

能够进行迭代逐一返回其成员项的对象称为可迭代对象。可迭代对象包括:

  • 所有序列类型,如list,str,tuple,range
  • 非序列类型:dict,set,文件对象:open(xx,)
  • 实现了__iter__()方法的任意对象(可迭代协议)
class MyClass:
    # 实现迭代协议
    def __iter__(self):
        return iter([11,22,33])
  • 实现了序列语义的__getitem__()方法任意对象:
class MyClass:
    v = [11,22,33]
    # 实现序列语义
    def __getitem__(self,item):
        return self.v[item]

能够通过for 遍历的都可以称为可迭代对象

3、迭代协议和迭代器协议

迭代协议

对象定义了一个__iter__方法,那么这个对象就是实现了迭代协议,__iter__方法的返回值必须是一个迭代器

迭代器协议

迭代器协议由一个__iter__方法和__next__方法共同构建,实现了这两个方法的对象就是实现了迭代器协议

list1 = [1,2,3]
it = iter(list1)  # 创建迭代器对象
print(next(it))   # 调用__next__输出下一个元素
print(next(it))
print(next(it))
print(next(it))

>>>
Traceback (most recent call last):
  File "F:\BaiduNetdiskDownload\auto39\day10\mytest.py", line 6, in <module>
    print(next(it))
StopIteration
1
2
3

4、迭代器(Iterator)

1、实现了迭代器协议的对象,就是一个迭代器

2、所有的可迭代对象,都可以通过内置函数iter()转换为迭代器

li = [1,2,3]
it = iter(li)

3、迭代器对象可以使用内置函数的next()进行迭代操作

li = [1,2,3]
it = iter(li)
print(next(it))
print(next(it))

4、所有的迭代器都是可迭代对象

5、生成器

什么是生成器,生成器有什么用?

生成器是一种特殊的迭代器,具备迭代器所有的特性,生成器内部不存储数据,只保存生成数据时的计算规则,在储存大量数据的时候,能够节约内存的开销

生成器表达式

生成器 = (i for i in range(10))

运行结果:

<generator object <genexpr> at 0x000001AB8DAF3C80>

generator是一个生成器对象

生成器函数

在函数中使用yeild关键字可以定义一个生成器函数,只要当函数中有yield这个关键字的时候,调用函数的返回就是一个生成器对象

def func():
    for i in range(10):
        yield i

# 调用函数
gen = func()

# 返回的是一个generator对象
print(type(gen))

# 可以使用next生成数据
print(next(gen))

>>>
<class 'generator'>
0

生成器和迭代器的区别

生成器属于迭代器的一种,如何区分生成器和迭代器

1、直接使用判断对象类型是iterator类型,还是generator类型

2、生成器比迭代器多了3个方法

send方法:在生成数据的同时,可以和生成器内部进行数据交互

close:生成可以调用close方法进行关闭

throw:可以在生成器内部上一次暂停的yield处引发一个指定的异常类型,生成器内部可以通过捕获异常来做不同的处理

例子:

def gen():
    print('-----第一次执行-------')
    val1 = yield 1
    print('-----第二次执行-------',val1)
    val2 = yield 2
    print('-----第三次执行-------',val2)
    val3 = yield 3
    print('-----第四次执行-------',val3)
    val4 = yield 4
    print('-----结束的执行-------',val4)

使用send方法:

g = gen()

print(next(g))
print('/n')
print(g.send('11111'))
print(next(g))
print(g.send('44444'))

 输出结果:

-----第一次执行-------
1
/n
-----第二次执行------- 11111
2
-----第三次执行------- None
3
-----第四次执行------- 11111
4

使用close方法:

g = gen()
g.close()
print(next(g))

输出结果:

Traceback (most recent call last):
  File "F:\BaiduNetdiskDownload\auto39\day10\mytest.py", line 19, in <module>
    print(next(g))
StopIteration

使用thorw方法

g = gen()
g.throw(ValueError)
print(next(g))

输出结果

Traceback (most recent call last):
  File "F:\BaiduNetdiskDownload\auto39\day10\mytest.py", line 18, in <module>
    print(g.throw(ValueError))
  File "F:\BaiduNetdiskDownload\auto39\day10\mytest.py", line 4, in gen
    def gen():
ValueError

使用生成器案例

使用生成器,生成名字,手机,邮箱数据信息

import faker


# 生成(名字 手机  邮箱)数据的生成器
def work():
    fk = faker.Faker(locale='zh_CN')
    val = yield 'Start'
    while True:
        if val == 1:
            # 生成手机号
            val = yield fk.phone_number()
        elif val == 2:
            # 生成名字
            val = yield fk.name()
        elif val == 3:
            # 生成邮箱
            val = yield fk.email()
        else:
            # 生成包含名字,手机号,邮箱的字典
            val = yield {'name': fk.name(), "mobile": fk.phone_number(), "email": fk.email()}


g = work()

next(g)

print(g.send(1))
print(g.send(2))
print(g.send(3))
print(g.send(4))

输出结果:

15250994328
黄楠
zhengjun@34.com
{'name': '李燕', 'mobile': '13601997855', 'email': 'junguo@gmail.com'}
举报

相关推荐

0 条评论