Python之高级特性

列表生成式

列表生成式就是一个用来生成列表的特定语法形式的表达式。 是Python提供的一种生成列表的简洁形式, 可快速生成一个新的list。

列表生成式实例

1. 生成一个2n+1的数字列表,n为从3到11的数字。

2. 求以r为半径的圆的面积和周长(r的范围从1到10)。

3. 找出1~100之间所有的质数。

4. 找出1~100之间所有奇数, 并且返回一个列表。如果能被3整除, 返回返回该数的平方,  否则返回该数的三次方 。

5.  给定一个列表li = [2,3,4,5,6,3,1,4,5], 如果是偶数返回0, 如果是奇数返回1。 

# 代码
# 1. 生成一个2n+1的数字列表,n为从3到11的数字。
print([i for i in range(3, 12)])

# 2. 求以r为半径的圆的面积和周长(r的范围从1到10)。
import math

print([(math.pi * r * r, 2 * math.pi * r) for r in range(1, 11)])


# 3. 找出1~100之间所有的质数。
def Prime_num(num):
    if num <= 1:
        return False
    else:
        for i in range(2, num):
            if num % i == 0:
                return False
        else:
            return True


print([i for i in range(1, 101) if Prime_num(i)])

# 4. 找出1~100之间所有奇数, 并且返回一个列表。如果能被3整除, 返回返回该数的平方,  否则返回该数的三次方 。
print([i ** 2 if i % 3 == 0 else pow(i, 3) for i in range(1, 101, 2)])

# 5.  给定一个列表li = [2,3,4,5,6,3,1,4,5], 如果是偶数返回0, 如果是奇数返回1。 
li = [2, 3, 4, 5, 6, 3, 1, 4, 5]
print([0 if i % 2 == 0 else 1 for i in li])

# 6. for循环里面嵌套for循环
print([i+j for i in range(1, 5) for j in range(4, 6)])

# 运行结果
[3, 4, 5, 6, 7, 8, 9, 10, 11]

[(3.141592653589793, 6.283185307179586), (12.566370614359172, 12.566370614359172), (28.274333882308138, 18.84955592153876), (50.26548245743669, 25.132741228718345), (78.53981633974483, 31.41592653589793), (113.09733552923255, 37.69911184307752), (153.93804002589985, 43.982297150257104), (201.06192982974676, 50.26548245743669), (254.46900494077323, 56.548667764616276), (314.1592653589793, 62.83185307179586)]

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

[1, 9, 125, 343, 81, 1331, 2197, 225, 4913, 6859, 441, 12167, 15625, 729, 24389, 29791, 1089, 42875, 50653, 1521, 68921, 79507, 2025, 103823, 117649, 2601, 148877, 166375, 3249, 205379, 226981, 3969, 274625, 300763, 4761, 357911, 389017, 5625, 456533, 493039, 6561, 571787, 614125, 7569, 704969, 753571, 8649, 857375, 912673, 9801]

[0, 1, 0, 1, 0, 1, 1, 0, 1]

[5, 6, 6, 7, 7, 8, 8, 9]

集合生成式和字典生成式

字典生成式:用来快速生成字典;

集合生成式:用来快速生成集合;

# 集合生成式
print({i + j for i in range(1, 5) for j in range(4, 6)})

# 字典生成式
print({i: i ** 2 for i in range(10)})


# 运行结果
{5, 6, 7, 8, 9}    
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

注意:集合生成式对比上面的列表生成式,去掉了其中的重复元素

集合生成式和字典生成式实例

1).  将字典的key值和value值调换;

# 1).  将字典的key值和value值调换;
dict = {i: i ** 2 for i in range(10)}
print(dict)
new_dict = {value: key for key, value in dict.items()}
print(new_dict)

# 运行结果
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
{0: 0, 1: 1, 4: 2, 9: 3, 16: 4, 25: 5, 36: 6, 49: 7, 64: 8, 81: 9}

2).  大小写计数合并 : 已知字典{'A':10, 'b':5, 'a':2}, 合并后为{'a':12, 'b':5}       key值最终全部为小写.

# 2).  大小写计数合并 : 已知字典{'A':10, 'b':5, 'a':2}, 合并后为{'a':12, 'b':5}  key值最终全部为小写.
# 方法1:传统方法
dict= {
    'A':10,
    'b':40,
    'B':10,
    'a':2,
    'D':5
}
new_dict = {}
for key, value in dict.items():
    if key.lower() not in new_dict:
        new_dict[key.lower()] = value
    else:
        new_dict[key.lower()] = new_dict[key.lower()]+ value
print(new_dict)
#方法2:字典生成式
dict= {
    'A':10,
    'b':40,
    'B':10,
    'a':2,
    'D':5
}

# 合并字典; d.get(key.lower(), 0), 如果key'值不存在,默认返回0;
new_dict = {key.lower():dict.get(key.lower(), 0) + dict.get(key.upper(), 0)for key, value in dict.items()}
print(new_dict)

# 运行结果
{'a': 12, 'b': 50, 'd': 5}
{'a': 12, 'b': 50, 'd': 5}

3). 假设有20个学生,学生分数在60-100之间,筛选出成绩在90分以上的学生;

# 3). 假设有20个学生,学生分数在60-100之间,筛选出成绩在90分以上的学生;
import random
scores = []
for i in range(20):
    score = random.randint(60, 100)
    scores.append(score)
print(scores)

print([score for score in scores if score > 90])

# 运行结果
[73, 82, 74, 92, 63, 89, 72, 80, 75, 72, 75, 71, 81, 99, 96, 83, 68, 95, 91, 71]
[92, 99, 96, 95, 91]

生成器Generator

什么叫生成器?

在Python中,一边循环一边计算的机制,称为生成器:Generator

什么时候需要使用生成器?

一般情况下我们不需要使用生成器,只有当我们因为性能限制才需要用到,比如我们使用python读取一 个10g的文件,如果一次性将10g的文件加载到内存处理的话(read方法),内存肯定会溢出;这里如果可以 使用生成器把读写交叉处理进行,比如使用(readline和readlines)就可以再循环读取的同时不断处理, 这样就可以节省大量的内存空间.

如何创建生成器?

第一种方法: 列表生成式的改写          []改成()

# 第一种方法: 列表生成式的改写。 []改成()
nums = (i**2 for i in range(100))
print(nums)
print(type(nums))

# 运行结果
<generator object <genexpr> at 0x7f477465f480>
<class 'generator'>

第二种方法: yield关键字

如果函数里面有yield关键字, 这个函数的返回值是生成器
如果遇到yield, 函数停止执行, 当再次调用next方法时, 从停止的地方继续执行

def fun():
    print('step 1')
    yield 'step 2'  # 遇到yield, 函数停止执行, 当再次调用next方法时, 从停止的地方继续执行
    print('step 3')
    yield 'step 4'


result = fun()  # 如果函数里面有yield关键字, 这个函数的返回值是生成器
print(result)  # <generator object fun at 0x7fd8917b42a0>
for i in result: # 打印生成器的每一个元素
    print(i)

# 运行结果
<generator object fun at 0x7fd8917b42a0>
step 1
step 2
step 3
step 4

如何打印生成器的每一个元素呢?

通过for循环, 依次计算并生成每一个元素

# 打印生成器的每一个元素
nums = (i**2 for i in range(10))

for num in nums:
    print(num)

# 运行结果
0
1
4
9
16
25
36
49
64
81

如果要一个一个打印出来,可以通过next()函数获得生成器的下一个返回值

# 每执行一次next打印一个值
print(next(nums))
print(next(nums))
print(next(nums))
print(next(nums))
print(next(nums))
print(next(nums))
print(next(nums))
print(next(nums))

# 运行结果
0
1
4
9
16
25
36
49

 for循环时如何封装next方法的(异常处理)

# next方法的异常处理

while True:
    try:
        print(next(result))
    except:
        break

生成器的特点是什么?

1.  节约内存

2.  迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的

send方法: 给生成器传递数据

# send方法: 给生成器传递数据
# 面向切面编程
def fun():
    while True:
        print('welcome......')
        receive = yield  'hello'
        print(receive)


# f是生成器
f = fun()
in_function = next(f)
print("函数里面返回的值:", in_function)
f.send("西部开源")

# 运行结果
welcome......
函数里面返回的值: hello
西部开源
welcome......

注意:此处尽量采用Debug调试,可以更清晰的理解过程(重要)

生成器的应用案例:

斐波那契数列 除第一个和第二个数外,任意一个数都可由前两个数相加得到. 1, 1, 2, 3, 5, 8, 13, 21, 34,    ...

# 显示n个fib数列
def fib(n):
    # a代表第一个数, b代表第2个数, 也就是要显示的数; count: 当前已经显示fib数列的个数;当前为0;
    a, b, count = 0, 1, 0
    while count < n:
        yield  b
        a, b = b, a+b
        count += 1

# f是一个生成器(函数里面有yield)
f = fib(10)

while True:
    try:
        print(next(f))
    except:
        break

# 运行结果
1
2
3
5
8
13
21
34
55

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值