【python】可迭代对象、迭代器、生成器、推导式

可迭代对象

在python中具有__iter__方法的对象就是可迭代对象。

验证可迭代对象

dir方法,返回一个列表,包含对象的全部方法

代码:

name = "123"
print(dir(name))

结果:

['__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', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

可迭代对象优缺点

优点:可以直观的查看里面的数据。
缺点:占用内存,不能迭代取值(迭代一个可迭代对象时,for循环底层会先将可迭代对象转换为迭代器,再进行迭代)。

迭代器

在python中具有__iter__方法和__next__方法的对象就是迭代器

验证迭代器

o1 = 'abcd' # 可迭代对象
o2 = [1, 2, 3] # 可迭代对象
o3 = (1, 2, 3) # 可迭代对象
o4 = {'name': '张三','age': 18} # 可迭代对象
o5 = {1, 2, 3} # 可迭代对象
f = open('file',encoding='utf-8', mode='w') # 迭代器
print('__iter__' in dir(o1))  # True
print('__iter__' in dir(o2))  # True
print('__iter__' in dir(o3))  # True
print('__iter__' in dir(o4))  # True
print('__iter__' in dir(o5))  # True
print('__iter__' in dir(f))  # True

print('__next__' in dir(o1))  # False
print('__next__' in dir(o2))  # False
print('__next__' in dir(o3))  # False
print('__next__' in dir(o4))  # False
print('__next__' in dir(o5))  # False
print('__next__' in dir(f))  # True
f.close()

可迭代对象转换为迭代器

代码:

count = "abc"
print("__iter__" in dir(count))
print("__next__" in dir(count))
obj = count.__iter__()
# obj = iter(obj)
print("-"*10)
print("__iter__" in dir(obj))
print("__next__" in dir(obj))

结果:

True
False
----------
True
True

迭代器取值

代码:

l1 = [1,2,3,4,5]
l2 = l1.__iter__()
print(l2.__next__())
print(l2.__next__())
print(l2.__next__())
print(l2.__next__())
print(l2.__next__())

结果:

1
2
3
4
5

模拟for循环机制

代码:

def myfor(obj):
    obj = iter(obj)
    while 1:
        try:
            print(obj.__next__())
        except Exception: #当next取不到值是报错,使用try结束循环
            break
myfor("abc")

结果:

a
b
c

迭代器优缺点

优点:

  1. 节省内存
    迭代器在内存中相当于只占一个数据的空间:因为每次取值都上一条数据会在内存释放,加载当前的此条数据。
  2. 惰性机制
    next一次,取一个值

缺点:

  1. 不能直观的查看里面的数据。

迭代器特性

  1. 迭代器是一次性的
  2. 不能逆向运行
  3. 惰性机制

生成器

在 Python 中,使用了 yield 的函数被称为生成器,生成 器本质是一个迭代器,区别在于迭代器是python提供的,生成器是自己写的。

构建生成器

将函数中的return换成yield后,这个函数就变成了生成器

def func():
    yield 1
    yield 2
    yield 3

生成器取值

代码:

def func():
    yield 1
    yield 2
    yield 3
    yield 4
s = func()
print(s.__next__())
print(s.__next__())
print(next(s))
print(next(s))

结果:

 1
 2
 3
 4

使用__next__或者next()方法都能够进行取值,如果取值次数大于yield的次数,就会报错

错误取值方式:

代码:

def func():
    yield 1
    yield 2
    yield 3
print(func().__next__())
print(func().__next__())
print(func().__next__())

结果:

1
1
1

yield from

如果返回的是一个可迭代对象yield会将整个可迭代对象返回,而yield from会将可迭代对象中每一个数据作为生成器的结果返回

yield

代码:

def func():
   li = [1,2,3]
   yield li
s = func()
print(s.__next__())

结果:

[1, 2, 3]

yield from

代码:

def func():
   li = [1,2,3]
   yield from li
s = func()
print(s.__next__())
print(s.__next__())
print(s.__next__())

结果:

1
2
3

生成器的特点

  1. 惰性机制
  2. 不可逆行
  3. 一次性的
  4. yield可以多次返回内容
  5. 一条next对应一个yield
  6. yield可以记录执行位置
  7. yield可以临时停止循环

对第七条特点的验证

代码:

def func():
   while 1:
       yield 1
s = func()
print(s.__next__())
print(s.__next__())
print(s.__next__())

结果:

1
1
1

推导式

推导式,也叫解析式,是python的一种独特用法,能从一个数据序列创建另一个数据序列的语法格式

列表推导式

代码:

li = [i for i in range(10)]
print(li)

结果:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

字典推导式

代码:

dic = {i:i+1 for i in range(10)}
print(dic)

结果:

{0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10}

集合推导式

代码:

se = {i for i in range(10)}
print(se)

结果:

{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

生成器表达式

使用括号的推导式得到的结果并不是元组,而是一个生成器
代码:

s = (i for i in range(10))
print(s)
print(next(s))
print(next(s))
print(next(s))

结果:

<generator object <genexpr> at 0x000002121675B0F8>
0
1
2

添加条件

在推导式中可以使用条件语句控制结果

代码:

li = [i for i in range(10) if i%2==0]
print(li)

结果:

[0, 2, 4, 6, 8]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值