python3---[列表;字典;集合]*生成式;生成器

<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]
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值