#内部含有__iter__方法的都是可迭代对象
for i in '123':
print(i)
print(dir('123'))#输出对象所有内部方法
print('__iter__' in dir(str))#True
print('__iter__' in dir(dict))#True
print('__iter__' in dir(list))#True
print('__iter__' in dir(set))#True
print('__iter__' in dir(int))#False
print('__iter__' in dir(bool))#False
#迭代器:可迭代对象通过__iter__()方法可以转换成迭代器,满足迭代器协议
#内部含有 __iter__() 和 __next__() 方法的就是迭代器
a = [1, 2, 3]
a_obj = a.__iter__()
print(a_obj)#<list_iterator object at 0x7fdabad7ffd0>
#1、迭代器取值 .__next__(),惰性机制
print(a_obj.__next__())#1
print(a_obj.__next__())#2
print(a_obj.__next__())#3
#2、for循环,对迭代对象执行__iter__()转换成迭代器,然后使用迭代器协议实现循环
for i in a_obj:
print('i', i)
#判断是否迭代器
#第一种方式:
print('__next__' in dir(a_obj))#True
#第二种方式
from collections import Iterable#迭代对象
from collections import Iterator#迭代器
#isinstance 判断一个对象是否是一个已知的类型,类似type(),比type()更广泛,考虑继承关系
print(isinstance('123', Iterable))#True
print(isinstance('123', Iterator))#False
print(isinstance(a_obj, Iterable))#True
print(isinstance(a_obj, Iterator))#True
#迭代器特点:
"""
1、节省内存
2、满足惰性机制
3、取值过程不可逆
"""
#生成器:本质也是迭代器,满足迭代器特点, 是Python写的迭代器
#1、通过生成器函数构建;2、通过生成器推导式构建
def test1():
print('test1')
yield 123
a = 1
b = 2
print(a)
print(b)
yield a
test1_obj = test1()#生成器对象初始化
print(test1_obj)#<generator object test1 at 0x7f8dcba69ac0>
print(test1_obj.__next__())#test1 123
#每个__next__()执行到yield停止,下次__next__()继续执行
print(test1_obj.__next__())#1 2 1
#2、send 把值赋给上一个yield, 所以第一个不能用send,需要用next
def test3():
print("test3")
# yield 1
a = yield 1
print("test3", a)
yield 2
print("test3", a)
yield 3
test3_obj = test3()
print(test3_obj.__next__(), 'M')#test3 1 M
print(test3_obj.send(555), "M2")#test3 555 2 M2
print(test3_obj.send(666), "M3")#test3 555 3 M3
#3、最后一个yield无法获取send的值
#列表推导式。一句话生成需要的列表
#优点:简单
#缺点:不能debug,占内存
#普通类别
li = []
for i in range(1, 6):
li.append(i)
#推导式
L1 = [i for i in range(1, 6)]#[变量 for 变量 in 可迭代对象] 遍历模式
print(L1)
L2 = ["test%s" % (i) for i in range(1, 6)]# 变量是可加工的
print(L2)
L3 = [i + 'test' for i in L2]
print(L3)
##[变量 for 变量 in 可迭代对象 if 条件] 筛选模式
L3 = [i for i in range(1, 101) if i % 2 == 1]
print(L3)
#生成器表达式,与推导式类似,使用小括号
#(变量 for 变量 in 可迭代对象)
#优点,节省内存
L4 = (i for i in range(1, 6))
print(type(L4))
#*扩展: 还有字典推导式、集合推导式,例:
#字典推导式
dic1 = {'name': 'Jerry', 'age': 30}
dic2 = {k: v for k, v in dic1.items() if k == 'name'}
print(dic2)
#集合推导式
L5 = [1, 2, 3, 5, 6, 6, 7]
s1 = {i for i in L5}
print(s1)
#练习
#求20以内所有能被3整除数的平方
L6 = [i**2 for i in range(1, 20) if i % 3 == 0]
print(L6)
#将列表中包含两个a的元素放到新列表中
L7 = [['aa', 'bb'], ['cc', 'acac']]
L8 = [y for x in L7 for y in x if y.count('a') == 2]
print('L8', L8)
#将字典的key,value对调
dic3 = {'k1': 'v1', 'k2': 'v2'}
dic4 = {v: k for k, v in dic3.items()}
print(dic4)
#例题:
# 1、过滤列表中长度小于3的元素,并转换为大写
L9 = ['test1', 'test2', 'a', 'b', 'test3']
L10 = [i.upper() for i in L9 if len(i) > 3]
print(L10)#['TEST1', 'TEST2', 'TEST3']
# 2、求(x, y)其中x是0-5直接的偶数,y是0-5直接的奇数组成的元组列表
L11 = [(x, y) for x in range(6) if x % 2 == 0 for y in range(6) if y % 2 == 1]#支持循环嵌套
print(L11)#[(0, 1), (0, 3), (0, 5), (2, 1), (2, 3), (2, 5), (4, 1), (4, 3), (4, 5)]
# 3、将50以内能被3整除的数的平方放入一个列表
L12 = [i ** 2 for i in range(50) if i % 3 == 0]
print(L12)#[0, 9, 36, 81, 144, 225, 324, 441, 576, 729, 900, 1089, 1296, 1521, 1764, 2025, 2304]
# 4、用推导式创建列表['test1', 'test2', 'test4']
L13 = ['test%s' % i for i in range(1, 5) if i != 3]
print(L13)
# 5、将列表['aaa', 'bbb', 'ccc']修改为['aaa1', 'bbb2', 'ccc3']
L14 = ['aaa', 'bbb', 'ccc']
L15 = [i+str(L14.index(i)+1) for i in L14]
print(L15)
# 6、将下面数据使用列表推导式取值
js = {
'type': 'test',
'msg': [
{'name': 'test1',
'age': 27},
{'name': 'test2',
'age': 23},
{'name': 'test3',
'age': 33}
]
}
"""
[['test1', 27],
['test2', 23],
['test3', 33]]
"""
L16 = [[i['name'], i['age']] for i in js['msg']]
print(L16)