<1>列表生成式
[experssion for item in 序列 if 判断语句]
1>列表生成式的简单应用
1.接收变量k,a,b
s = '51 5000 10000'
# for循环
li = []
for item in s.split():
li.append(int(item))
k,a,b = li
print(k,a,b)
# 列表生成式
k,a,b=[int(item) for item in s.split()]
print(k,a,b)
print([i for i in range(1, 11) if i % 2 == 0])
print([i + j for i in 'ABC' for j in '123'])
print([i + str(v) for i, v in zip(['A', 'B', 'C'], [1, 2, 3])])
生成一个列表,列表元素为偶数的平方次幂
li = [i ** 2 for i in range(1, 8) if i % 2 == 0]
print(li)
1>列表生成式的应用
应用1:找出1~1000之间的所有质数
应用2:将3x3的矩阵转换成一堆数组
应用3:列表中所有内容都变成小写
应用4:找出/var/log目录中,所有以.log结尾的文件名或者目录名
应用5:求以1~10之间所有偶数为半径所有圆的面积
print([math.pi * r * r for r in range(2, 11, 2)])
import math
# 方法一:
li = []
for r in range(2, 11, 2):
square = math.pi * r * r
li.append(square)
print(li)
# 方法二:
print([math.pi * r * r for r in range(2, 11, 2)])
# 方法三:
def square(r):
# 求以r为半径的圆
res = math.pi *r*r
return res
print([square(r) for r in range(2,11,2)])
应用6:
给定一个正整数,编写程序计算有多少对质数的和等于输入的这个正整数,并输出结果。
输入值小于1000。输入为10, 程序应该输出结果为2。(共有两对质数的和为10,分别为(5,5),(3,7))
- 输入描述:
输入包括一个整数n,(3 ≤ n < 1000)
- 输出描述:
输出对数
- 示例1 :
输入:
10
输出:
2
方法一:
方法二:
<2>字典生成式
需求1:假设有20个学生,学生分数在60~100之间,筛选出成绩在90分以上的学生
需求2:将所有的key值变为大写
需求3:大小写key值合并,统一以小写输出
<3>集合生成式
print({i ** 2 for i in {1, 2, 3}})
print({i ** 2 for i in {1, 2, 3, 9, 12} if i % 3 == 0})
<4>生成器
创建生成器的方法1:
In [7]: nums = (x*2 for x in range(10))
In [8]: nums
Out[8]: <generator object <genexpr> at 0x7fb2a6137fc0>
In [9]: for num in nums:
...: print(num)
...:
0
2
4
6
8
10
12
14
16
18
创建生成器的方法2(定义一个函数,让这个函数变成生成器)
定义一个函数实现斐波那契数列:1 1 2 3 5 8 13…
def fib(num):
a,b,count = 0,1,1
while count <= num:
print(b)
a,b = b,a+b
count +=1
fib(10)
如果在调用函数的时候,发现这个函数中有yeild
那么此时,也就不是调用函数了,而是创建了一个生成器对象
<5>生成器的理解和应用
def creat_num(all_num):
print('~~~~~~~~~~~~1~~~~~~~~~~~')
a, b = 0, 1
current_num = 0
while current_num < all_num:
print('~~~~~~~~~~~~2~~~~~~~~~~~')
# 相当于暂停程序
yield b
print('~~~~~~~~~~~~3~~~~~~~~~~~')
a, b = b, a + b
current_num += 1
print('~~~~~~~~~~~~4~~~~~~~~~~~')
obj = creat_num(5)
# 返回生成器对象
print(obj)
# 用for循环不断调用yield,生成数列
for num in obj:
print(num)
# 调用next()分步执行,遇到yield就中断
ret = next(obj)
print(ret)
ret1 = next(obj)
print(ret1)
ret2 = next(obj)
print(ret2)
ret3 = next(obj)
print(ret3)
ret4 = next(obj)
print(ret4)
# 执行5次yield后,已经没有yield可执行了,所以第6次调用next()会报错
# ret5 = next(obj)
# print(ret5)
此时.我们发现程序会报错(告诉我们,生成器里面没有东西了)
while True:
try:
ret = next(obj)
print(ret)
except Exception as red:
print(red.value)
break
# 两个生成器对象之间并没有任何关系
obj2 = creat_num(5)
ret6 = next(obj2)
print(ret6)
生成器_send
使用send唤醒程序
使用send()函数来唤醒程序执行,使用send()函数的好处是
可以在唤醒的同时向断点中传入一个附加的数据
def create_num(all_num):
a,b = 0,1
current_num = 0
while current_num < all_num:
ret = yield a
print('>>>>>>>>ret>>>>>>>',ret)
a,b = b,a+b
current_num += 1
obj = create_num(100)
# next()不传递值
red = next(obj)
print(red)
# send传递值
red = obj.send(None)
print(red)
next和send得到的都是yield后面的值
不同的是send传递值而next不传递值
注意:
不能把send放在第一个,因为第一次执行程序是从开始执行
并没有值来接收send
如果你非要把send放在第一个,那么传递的值应该是None
生成器应用
实现多任务
并行(真的):有两个任务,两个cpu,一个任务占一个cpu
并发(假的):有四个任务,两个cpu,四个任务交替占有cpu执行
import time
def task1():
while True:
print('~~~~~~1~~~~~~')
time.sleep(0.1)
yield
def task2():
while True:
print('~~~~~~2~~~~~~')
time.sleep(0.1)
yield
def main():
t1 = task1()
t2 = task2()
"""
类似于两个while True一起执行
先让t1运行一会,当t1遇到yield的时候,再返回到task2()
然后执行t2,当它遇到yield的时候,再次切换到t1中
这样t1/t2/t1/t2的交替运行,最终实现了多任务---->协程
"""
while True:
next(t1)
next(t2)
main()
实现单线程并发
利用了关键字yield一次性返回一个结果,阻塞,重新开始
send 唤醒
import time
def consumer(name):
print('%s 准备学习了~' %(name))
while True:
lesson = yield
print('开始[%s]了,[%s]老师来讲课了~' %(lesson,name))
def producer():
c1 = consumer('A')
c2 = consumer('B')
c1.__next__()
c2.__next__()
print('同学们开始上课了~')
for i in range(3):
time.sleep(1)
print('到了两个同学')
c1.send(i)
c2.send(i)
producer()
使用greenlet完成多任务
为了更好的使用协程来完成多任务,python中的greeblet模块对其进行的封装
下载greenlet:/usr/local/python3/bin/pip3 install greenlet
from greenlet import greenlet
import time
def test1():
while True:
print('~~~~~1~~~~~')
gr2.switch()
time.sleep(0.5)
def test2():
while True:
print('~~~~~2~~~~~')
gr1.switch()
time.sleep(0.5)
# greenlet这个类对yield进行的封装
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()
使用gevent完成多任务
使用greenlet时需要 gr1.switch( ) 和 gr1.switch( ) 手动切换
gevent则不需要,gevent:三个任务同时进行
import gevent
def f1(n):
for i in range(n):
print(gevent.getcurrent(), i)
gevent.sleep(0.5)
def f2(n):
for i in range(n):
print(gevent.getcurrent(), i)
gevent.sleep(0.5)
def f3(n):
for i in range(n):
print(gevent.getcurrent(), i)
gevent.sleep(0.5)
g1 = gevent.spawn(f1, 5)
g2 = gevent.spawn(f2, 5)
g3 = gevent.spawn(f3, 5)
g1.join()
g2.join()
g3.join()
gevent实现多张图片同时下载
下载图片:
import urllib.request
def main():
req = urllib.request.urlopen('https://img3.doubanio.com/view/photo/m/public/p2528834770.jpg')
img_content = req.read()
with open('1.jpg','wb') as f:
f.write(img_content)
main()
下载多张图片:
import urllib.request
import gevent
def downloder(img_name,img_url):
req = urllib.request.urlopen(img_url)
img_content = req.read()
with open(img_name,'wb') as f:
f.write(img_content)
def main():
gevent.joinall([
# 图片名 图片地址链接
gevent.spawn(downloder,'2.jpg','https://img3.doubanio.com/view/photo/m/public/p2528834770.jpg'),
gevent.spawn(downloder,'3.jpg','https://img1.doubanio.com/view/photo/l/public/p2541840518.jpg'),
gevent.spawn(downloder,'4.jpg','https://img3.doubanio.com/view/photo/l/public/p2540519750.jpg'),
gevent.spawn(downloder,'4.jpg','https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1544239785&di=0dac6c76bd63b935147a034cbf1ff1aa&src=http://image11.m1905.cn/uploadfile/2018/ss/1023/20181023110107782.jpg')
])
main()
<6>应用题
应用1
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如,罗马数字2写做 II,即为两个并排放置的的 1,12写做XII,即为 X + II ,27写做XXVII,即为XX+V+II
在罗马数字中,小的数字在大的数字的右边。但 4 不写作 IIII,而是 IV。
数字 1 在数字 5 的左边,所表示的数等于大数减小数得到的数值 4 。
*同样地,数字 9 表示为 IX。这个规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 范围内
示例:
示例 1:
输入: “III”
输出: 3
示例 2:
输入: “IV”
输出: 4
示例 3:
输入: “IX”
输出: 9
示例 4:
输入: “LVIII”
输出: 58
解释: C = 100, L = 50, XXX = 30 and III = 3.
示例 5:
输入: “MCMXCIV”
输出: 1994
解释: M = 1000, CM = 900, XC = 90 and IV = 4.
应用二:
编写一个函数来查找字符串数组中的最长公共前缀
如果不存在最长公共前缀,返回空字符串 ''
示例 1:
输入: [“flower”,”flow”,”flight”]
输出: “fl”
示例 2:
输入: [“dog”,”racecar”,”car”]
输出: “”
解释: 输入不存在最长公共前缀
说明:所有输入只包含小写字母 a-z
[1]
[2]