1、能循环的数据类型:list,dict,str,set,tuple,f=open(),range(),enumerate();
2、dir([]):可查看列表的所有方法,类似dir({}),dir(")……
3、只要是for循环就有__iter__()方法,也就是可迭代的iterable.
4、带双下划线的方法为双下方法,很少直接调用,一般通过其他语言触发的。例如:[].add([])=[]+[];
5、求交集:set([]&[])
迭代器
- 迭代器:一个列表执行了__iter__()之后的返回值就是一个迭代器;
- 元素个数:[].iter().length_hint();
- 迭代器协议:内容含有__next__和__iter__方法的就是迭代器(iterator)→判断是否是迭代器:iterator,range;
- [].iter()迭代器→通过__next__方法就可以从迭代器中一个一个的取值;
- for+可迭代的数据类型/迭代器,for循环实际上就是使用迭代器;
可迭代的
- 可迭代的协议:只要含有__iter__方法的都是可迭代的,或者只要能for循环的都是可迭代的(可迭代协议在for循环中,首先会找iter,如有这个方法才能进行循环);
总结
- 迭代器一定可迭代,可迭代的通过调用iter()方法就得到一个迭代器。
- 只有是可迭代对象才能用for
- 当我们遇到一个新的变量,不确定能不能用for循环的时候,就判断它是否是可迭代的。
迭代器的好处:
- ①从容器类型中一个一个的取值,会把所有的值都去到;
- ②节省内存空间(要用时才会生成,不会是已经生成了的),如range(),f=open()——迭代器并不会在内存中占用一大块内存,而是随着循环,每次生成一个,每次next就给出一个
- ③一个迭代器只能从头到尾取一次,不能重复取或向回取。
注意:一个迭代器只能逐个取值一次。
句柄handler:with open() as f,也叫文件操作符。
生成器进阶(send)
- g=f()生成器→g.send(None)相当于__next__方法,send与next效果一致,只是在获取下一个值的时候,给上一值的位置传递一个数据,传进去的值是上一个yield的值
- 使用send的注意事项:①第一次使用生成器的时候,是用next获取下一个值(必须);②最后一个yield不能接受外部的值或新的值;③send的作用范围和next一模一样。
'''生成器进阶——send'''
def func():
print('hello word')
content=yield 1
print('======',content)
yield 2
print('i like python')
yield 3
g=func()
ret=g.__next__()
print(ret)
ret=g.send('something')#这里有点类似于__next__的方法,但是一定是来第一个yield之后,因为在这里的函数内,第一次取值的时候到yield 1就结束了
#要到第二次取值的时候才会执行content=yield 1,而g.send(),就是把值传给content,send(None)则不传任何值进去
print('aaaaaaaaa')
print(ret)
ret=g.__next__()
print('aaaaaaaaa')
print(ret)
输出结果:
hello word
1
====== something
aaaaaaaaa
2
i like python
aaaaaaaaa
3
运行过程
在python3中:yield from可遍历每个元素,可代替for循环。
'''yeild from 代替for循环,在python3中的功能'''
def func():
x='abcdefg'
y='uoters'
yield from x
print('=======')
yield from y
f=func()
for i in f:
print(i)
输出结果:
a
b
c
d
e
f
g
=======
u
o
t
e
r
s
生成器表达式
- (i for i in range(10))→括号,返回生成器
- [i for i in range(10)]→列表推导式
- 生成器表达式与列表推导式都只能解决简单的问题,其区别为:括号不一样,返回值不一样(几乎不占用内存)
各种推导式
①列表推导式
- [每个元素或者是和元素相关的操作,for元素in 可迭代数据类型(遍历之后挨个处理)]
- [满足条件的元素相关操作 for 元素 in 可迭代数据类型 if 元素相关的条件(筛选功能)]
②生成器表达式:列表推导式改为括号()
除了上述的两种推导式,还有字典推导式,集合推导式(自带去重)
lst=['鸡蛋%s'%i for i in range(10)]#这种形式也叫做列表推导式
print(lst)
hens=('鸡蛋%s'%i for i in range(3))#生成器表达式:相对于列表推导式,返回值不一样,这里返回的是生成器,几乎不占用内存
#注意与列表推导式不一样的括号
for i in hens:
print(i)
data=(i**2 for i in range(2))
for i in data:
print(i)
#30以内能整除3的数
lst_3=[i for i in range(10) if i%3==0]
print(lst_3)
#在嵌套列表里筛选特定条件的元素
txt=[['Tony','Steven','Jack','Steven'],['Even','Eileen','Cici']]
names=[name for lst in txt for name in lst if name.count('e')==2]
print(names)
#字典推导式
#案例1:字典的key和value对调位置,这里要求key和value必须是可哈希的
dct={'a':8,'b':9}
dct_new={dct[k]:k for k in dct}
print(dct_new)
#案例2:合并大小写对应的value值,将k统一小写
m={'a':10,'b':34,'A':7,'Z':3}
m_new={k.lower():m.get(k.lower(),0)+m.get(k.upper(),0) for k in m.keys() if m.keys()}
print(m_new)
#集合推导式,自带去重的功能
k={i**2 for i in [1,-1,2]}
print(k)
输出:
['鸡蛋0', '鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4', '鸡蛋5', '鸡蛋6', '鸡蛋7', '鸡蛋8', '鸡蛋9']
鸡蛋0
鸡蛋1
鸡蛋2
0
1
[0, 3, 6, 9]
['Steven', 'Steven', 'Eileen']
{8: 'a', 9: 'b'}
{'a': 17, 'b': 34, 'z': 3}
{1, 4}