列表推导式
# 列表推导式就是使用一个简单的方法创建一个列表
# 列表里元素的类型是根据for前面的数据类型而定的
a = [m for m in range(31)]
print(a)# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
b = [a[m:m + 3] for m in range(0, 31, 3)]# 这里的a就是上面定义的a列表
print(b)# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14], [15, 16, 17], [18, 19, 20], [21, 22, 23], [24, 25, 26], [27, 28, 29], [30]]
c = [(a, b) for a in range(0, 2) for b in range(3, 5)]
print(c)# [(0, 3), (0, 4), (1, 3), (1, 4)]
i = [[1, 4, 7],
[2, 5, 8],
[3, 6, 9]]
d = [row[1] for row in i]
print(d) # [4, 5, 6]
e = [i[j][j] for j in range(len(i))]
print(e) # [1, 5, 9]
f = [i[j][2-j] for j in range(len(i))]
print(f)# [7, 5, 3]
循环后面也可以跟判断,这样就可以进行简单的数据过滤了
看下面的演示:
num3 = [1,-1,2,-2,-10,3,4]
print([x for x in num3 if x > 0])# [1, 2, 3, 4]
求100以内的偶数和,求100以内所有能被3整除的且个位为2的数,还有很多相同类型的,同样可以使用这种方式得出:
(虽然说这种也可以通过修改步长得出,但讲还是要讲一下的)
num1 = [x for x in range(101) if x % 2 == 0]# 这里我就不去打印了
print(sum(num1))# 2550
print([i for i in range(101) if i % 3 == 0 and i % 10 == 2])# [12, 42, 72]
还可以对列表中的值进运算,就比如进行幂运算
print([i ** 2 for i in range(5)])# [0, 1, 4, 9, 16]
求一个数的所有因子,这个可以对判断一个数是否是完数有帮助,只需要把n+1换成n就好了,然后在求和进行比较
(所谓完数就是该数恰好等于除自身外的因子之和。例如:6=1+2+3)
n = 6
print([i for i in range(1,n+1) if n % i == 0])# [1, 2, 3, 6]
类推
有列表推导式,那有元组、字典、集合推导式吗?这是我们应该去想的
那我们现在就来尝试一下,无非就是换下包装而已
num = (i for i in range(5))
print(num) # <generator object <genexpr> at 0x09AEEE30>
print(type(num))# <class 'generator'>
# 显然好像不是元组
# 这是一个生成器对象
# 我们可以对他进行遍历,也可以使用next()方法去调用它
# 但是这样生成器只能使用一次,也不能说是使用一次吧,
# 就是当生成器里的数据被迭代完时,里面的数据就为空了
# 看下面的演示
for i in num :
print(i)
# 0
# 1
# 2
# 3
# 4
print(list(num))# []
# print(next(num))# 0
# print(next(num))# 1
# print(next(num))# 2
# print(next(num))# 3
# print(next(num))# 4
# print(list(num))# []
用()包裹的其实就是一个生成器表达式,在 Python 中,使用了 yield 的函数被称为生成器,跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器
# 定义一个返回前n个斐波那契数列生成器函数
def feibo(n):
a,b = 0,1
for i in range(n):
a,b = b ,a+b
yield a
print(feibo(10))# <generator object feibo at 0x09DDEEB0>
print(list(feibo(10)))# [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
当生成器表达式作为一个单独参数传递给函数时候的外面de()是可以省略的
使用一个生成器表达式作为参数会比先创建一个临时列表更加高效
s1 = sum((x for x in range(101))) # 显示的传递一个生成器表达式对象
s2 = sum(x for x in range(101)) # 更加优雅的实现方式,省略了括号
print(s1)# 5050
print(s2)# 5050
# min()、max()函数也是同理
person = [
{
'name':'zhangsan','age':20},
{
'name':'lisi','age':18},
{
'name':'wangwu','age':16},
{
'name':'maliu','age':17},
]
print(min(p['age'] for p in person))# 16
print(min(person,key=lambda p:p['age']))# {'name': 'wangwu', 'age': 16}
让我们看下{}
a = {
x for x in range(10)}
print(a)# {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
print(type(a))# <class 'set'>
student = {
'name':'zhangsan','age':18
}
b = {
x:y for y,x in student.items()}
print(b)# {'zhangsan': 'name', 18: 'age'}
print(type(b))# <class 'dict'>
感觉没什么用,就一个对字典进行反转还有那么一点用
需要重点掌握的还是列表推导式和生成器表达式