列表推导式
最终得到的是一个列表。
格式1:[i for i in 可迭代的]
格式2:[i for i in 可迭代的 if 条件] #for循环后,如果满足条件则放入列表
格式3:[结果1 if 条件 else 结果2 for 变量 in 可迭代的] #可读性比较差
格式4:[(i,j) for i in 可循环的 for j in 可循环的] #嵌套for循环
将1-20的数字放入列表
# 方法一:自己写一个列表
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
print(list1)
# 方法二:for循环
list2 = []
for i in range(1, 21):
list2.append(i)
print(list2)
# 方法三:列表推导式
list3 = [i for i in range(1, 21)]
print(list3)
---------------
输出:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
将1-50的偶数存入列表
list4 = [i for i in range(0, 51) if i % 2 == 0]
print(list4)
---------
输出:
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50]
集合推导式
集合推导式。格式就是将列表推导式的[]换成{}
set1 = {i for i in range(5)}
print(set1)
-------------
输出:
{0, 1, 2, 3, 4}
字典推导式
dict1 = {'a': 1, 'b': 2, 'c': 3}
new_dict = {key: value + 1 for key, value in dict1.items()}
print(new_dict)
--------------
输出:
{'a': 2, 'b': 3, 'c': 4}
生成器-generator
通过前面的列表生成器,可以生成一个很大的列表。但是同时当元素非常多的时候,也会很占空间。
所以说,元素可以按某种算法推算出来,就可以不用占用那么多空间了。Python中这种机制,就叫做生成器generator。
格式一-把列表推导式的[]换成()
generator1 = (x * x for x in range(5))
可以用next()获取generator中的下一个值。但是如果没有值了,还调用了next(),则会报错StopIteration。
generator1 = (x * x for x in range(5))
print(next(generator1))
print(next(generator1))
print(next(generator1))
print(next(generator1))
print(next(generator1))
-------------
输出:
0
1
4
9
16
生成器generator也是可迭代对象,可以直接可以用for循环输出,也不用考虑StopIteration报错。
generator1 = (x * x for x in range(5))
for i in generator1:
print(i)
格式二-yield
有些复杂的数列,生成器不太好写出来,但是用函数比较容易写出来。就可以结合yield将函数编程一个generator。
比如用函数生成斐波那契额数列。用函数可以方便地写出来,但是用生成器不太好写。
def fib(max):
n,a,b = 0,0,1
while n<max:
print(b)
a,b = b,a+b
n +=1
return 'end'
fib(8)
-------------------
输出:
1
1
2
3
5
8
13
21
只要用yield替换print的部分,就可以将函数变成一个generator
def fib(max):
n,a,b = 0,0,1
while n<max:
yield b
a,b = b,a+b
n +=1
return 'end'
g = fib(8)
print('g的类型',type(g))
for i in g:
print(i)
-----------
输出:
g的类型 <class 'generator'>
1
1
2
3
5
8
13
21
而且“函数”中有return的时候,必须要用expect捕获异常,return的值会以StopIteration错误类型的值的形式打印出来。
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n += 1
return 'end'
g = fib(5)
while True:
try:
print(next(g))
except StopIteration as err:
print('StopIteration:',err)
break
-------------
输出:
1
1
2
3
5
StopIteration: end
关于yield备注:
- 当函数中有yield的时候,函数就从普通函数,进化成了generator
- 函数的执行流程会发生变化。函数执行时,每次迭代的时候到了yield处就会停止。下一次迭代会从上次停止的yield处继续执行。
用一个更简单的例子演示一下yield的执行过程。
可以看到下面的函数,每次next()时,都是到yield结束;下次yield的时候又从上次结束的地方开始。
def func():
print('step 1')
yield 'a'
print('step 2')
yield 'b'
print('step 3')
yield 'c'
g = func()
print(next(g))
print('-------------->')
print(next(g))
print('-------------->')
print(next(g))
-------------
输出:
step 1
a
-------------->
step 2
b
-------------->
step 3
c
func()会新建一个generator。所以以下示例三次next()每次都会新建独立的generator对象。所以每次都只输出到第一次yield出现的地方。
def func():
print('step 1')
yield 'a'
print('step 2')
yield 'b'
print('step 3')
yield 'c'
print(next(func()))
print(next(func()))
print(next(func()))
------------
输出:
step 1
a
step 1
a
step 1
a
迭代器
可迭代的-Iterable
可被for循环的对象,就是可迭代的。其分为两类:
- 一类是集合数据,如:list、tuple、set、dict、str
- 一类是生成器generator和带yield的generator function
可以使用isinstance()判断一个对象是否是Iterable(可迭代的)。
from collections import Iterable
print(isinstance('abc', Iterable))
print(isinstance([], Iterable))
print(isinstance({}, Iterable))
print(isinstance((), Iterable))
print(isinstance((x for x in range(5)), Iterable))
print(isinstance(99, Iterable))
----------
输出:
True
True
True
True
True
False
迭代器-Iterator
可以被next()调用并不断返回下一个值的对象,称为迭代器:Iterator。
from collections import Iterator
print(isinstance('abc', Iterator))
print(isinstance([], Iterator))
print(isinstance({}, Iterator))
print(isinstance((), Iterator))
print(isinstance((x for x in range(5)), Iterator))
-----------------
输出:
False
False
False
False
True
Iterable转换Iterator
可以使用iter(),将可迭代的对象转换成迭代器。
from collections import Iterator
print(isinstance(iter('abc'), Iterator))
print(isinstance(iter([]), Iterator))
print(isinstance(iter({}), Iterator))
print(isinstance(iter(()), Iterator))
print(isinstance((x for x in range(5)), Iterator))
------------
输出:
True
True
True
True
True
总结
- 不是所有可迭代的对象(Iterable)都是生成器(Iterator)
- 所有生成器(Iterator),都是可迭代的对象(Iterable)
- 可以使用iter(),将可迭代的对象转换为生成器