推导式
列表推导式
将旧的列表通过推导产生新的符合需求的列表
格式:
[表达式 for 变量 in 旧列表] [表达式 for 变量 in 旧列表 if 条件] # 遍历旧列表元素,对于旧列表中取出的每一个元素(赋值给了for后的变量)若此变量符合条件,则将此变量传递给前方表达式,由表达式处理后加入待返回的列表中. [表达式1 if 条件 else 表达式2 for 变量 in 列表] # 对旧列表中的每一个元素((赋值给了for后的变量) 若其满足条件,则执行表达式1,否则执行表达式2 ,将执行结果加入新列表中
注:for-in-if
结构可以在中括号中存在多个,前方的表达式中的变量需要与for
中的变量对应一致
例如:
# 获取以1到1000的整数为元素的列表
res = [i for i in range(1001)]
# 获取列表中长度小于等于3的字符串
names = ['mike', 'jack', 'john', 'kai']
res = [name for name in names if len(name) <= 3]
print(res) # ['kai']
# 获取列表中长度大于3的元素,并将其首字母改为大写
names = ['mike', 'jack', 'john', 'kai']
res = [i.capitalize() for i in names if len(i) > 3]
print(res) # ['Mike', 'Jack', 'John']
# 获取1~100中可被3整除的元素组成的列表
res = [i for i in range(101) if i % 3 == 0]
print(res)
# 获取一个列表,其元素为还有两个元素的元组,每个元组的第一个元素为5以内的偶数,第二个元素为10以内的奇数
res = [(x, y) for x in range(1,5) if x % 2 == 0 for y in range(1,10) if y % 2 != 0]
print(res)
# 某列表re的元素为含有三个元素的列表,获取列表中各个子列表的最后一个元素组成的列表
res2 = [a[-1] for a in re]
print(res2)
# 某列表中元素为字典,各个字典中存储学生信息,若学生年龄少于18,则年龄加2,否则减3
集合推导式
格式:
{表达式 for 变量 in iterable} {表达式 for 变量 in iterable if 条件}
如:
# 将列表中的重复元素去除.
lists = [1, 2, 3, 1, 6, 88, 2, 3]
res = {i for i in lists}
print(res)
字典推导式
格式:
{表达式1:表达式2 for 变量列表 in 旧字典} # for 之前的格式必须为以冒号分隔的两个值的形式
# 颠倒字典中的键与值
res = {value : key for key, value in dicts.items()}
print(res)
生成器 generator
受内存的限制,列表的容量有限,当列表的元素数量十分巨大时(如里列表中有上百万个元素),若仅使用此种列表的前部少数几个元素,会消耗很多系统资源.
因此若列表中的元素可以按照一定的算法推算出来,则可不必创建完整的列表.
在Python中,一边循环一边计算的机制称作生成器
创建方式
- 通过
列表推导式
创建生成器(列表生成式) # 括号中的内容不包括列表生成式的中括号
gen = (x for x in range(100000)) print(type(gen)) # <class 'generator'> print(gen) # <generator object <genexpr> at 0x0000024779212DD0>
- 通过函数创建生成器
步骤:- 创建函数并在返回数据时使用关键字
yield
(其表示返回并暂停) - 调用此函数并用一变量接收此函数(接收后此变量即为生成器类型)
- 使用生成器的相关函数获取值
例:
注:def generate(): # 定义生成器 n = 0 while True: n += 1 yield n # 使用关键字 yield g = generate() print(type(g)) # <class 'generator'> # 斐波那契数列 def fib(): a, b = 0, 1 while True: yield b a, b = b, a + b g = fib() print(next(g)) print(next(g))
- 当使用函数方式获取生成器时,获取下一个元素后会暂停在
yield
之后,再次获取下一个元素时会在yield
之后继续执行. - 函数方式的生成器可以带有
return 语句
,但只在生成器中元素取尽之后才会执行,可以用来提示元素取尽
- 创建函数并在返回数据时使用关键字
从生成器中获取值
- 使用生成器内置函数
.__next__()
例:gen = (x for x in range(100000)) gen_next = gen.__next__() print(gen_next) # 0
- 使用系统内置函数
next(iterable, default)
注:若以获取了生成器中所有值,且未指定默认值,再次调用此方法则会报错参数 描述 iterable 必需。可迭代对象。 default 可选。在迭代结束时返回的默认值。
例:gen = (x for x in range(100000) if x % 3 ==0) gen_next = next(gen) print(gen_ne) # 0 gen_next = next(gen) print(gen_ne) # 3 gen_next = next(gen) print(gen_ne) # 6 # 获取生成器中所有元素 ## 使用循环来实现 ### ∵若不指定默认值,元素取尽后会报错 ∴需要进行异常处理 #### 指定默认值 gen = (x for x in range(100) if x % 3 == 0) while True: i = next(gen, '') if i == '' : break print(i) #### 不指定默认值 gen = (x for x in range(100) if x % 3 == 0) while True: try: i = next(gen) print(i) except: print('值已取尽!') break
内置函数send(value)
此函数有一个参数value
,该参数指定的是上一次被挂起的yield语句
的返回值.
调用此函数会返回yield语句
产生的值,并将参数传入生成器函数,将其作为yield语句
的返回值.
可以在生成器函数中借助此值控制生成器的执行
注:第一次使用此函数需要传入None
.
def fib():
i = 0
while i < 5:
temp = yield i
print('temp', temp)
i += 1
return 'end'
g = fib()
n0 = g.send(None) #1
print('n0', n0) #2
n1 = g.send('haha') #3
print('n1', n1) #4
n2 = g.send('hehe') #5
print('n2', n2) #6
'''
打印结果:
n0 0 # 此句为执行语句2的结果,之前的语句1执行后将yield语句产生的0赋给变量n0
temp haha #此句为执行语句3的结果,其参数haha指定为语句1调用后的yield语句的返回值,继续执行后,被赋给变量temp,后执行打印语句打印此值,追后执行到第二次yield语句,将值1返回并赋给变量n1
n1 1
temp hehe
n2 2
'''
生成器的应用–多任务—协程
将一个线程分为若干份,每份为一个协程.
在函数的相应位置添加关键字yield
或yield None
使其成为生成器函数,
# 函数1和函数2交替执行
def fun1(n):
for i in range(n):
print('AAAAAAA', i + 1)
yield
def fun2(n):
for i in range(n):
print('BBBBBBB', i + 1)
yield
g1 = fun1(3)
g2 = fun2(5)
while True:
try:
g1.__next__()
g2.__next__()
except:
pass
'''
结果
AAAAAAA 1
BBBBBBB 1
AAAAAAA 2
BBBBBBB 2
AAAAAAA 3
BBBBBBB 3
'''
迭代器
可迭代的对象
- 生成器
- 列表,元组,集合,字典,字符串
- 判断是否可迭代
使用系统内置函数isinstance(object, type)
,将参数type
指定为Iterable
(需要先引入typing
中的Iterable
,from typing import Iterable
)from typing import Iterable a = (x for x in range(10)) res = isinstance(a, Iterable) print(res)
迭代器
- 定义:可以被
next()
函数调用并不断返回下一个值的对象称为迭代器. - 迭代是访问集合元素的一种方式,迭代器时一个可以记住遍历位置的对象,
- 迭代器对象从集合或列表的第一个元素开始访问,直到所有元素访问结束.
- 迭代器只可向前不可向后.
- 可迭代的未必是迭代器(如list不是迭代器),
- 系统内置函数
iter(object, sentine)
返回迭代器对象,将可迭代的变为迭代器参数 描述 object 必需。可迭代对象。 sentine 可选。如果对象是可调用对象,则当返回值与前哨相同时,迭代将停止。 l = [1, 2, 3, 4, 5] i = iter(l) next1 = next(i) print(next1)