生成式与生成器

列表生成式

需求1:
#1.接收变量k,a,b

s = ‘51 5000 10000’
#普通循环
li = []
for item in s.split():

li.append(int(item))
k,a,b = li

print(k,a,b)

#列表生成式

li=[int(item) for item in s.split()]
print(li)
print(k,a,b)

需求2:生成一个列表,列表元素分别为[11,22,33,44…n*n]

li = []
#普通循环
for i in range(1,8):

li.append(i**i)

print(li)

#列表生成式

li = [i**i for i in range(1,8)]
print(li)

[experssion for item in 序列 if 判断语句]

li = [i ** 2 for i in range(1, 8) if i % 2 == 0]
print(li)

找出1~10之间的所有的偶数

print([i for i in range(1, 11) if i % 2 == 0])

找出1~1000之间的所有质数

def isPrime(num):

pass

print([i for i in range(1, 1000) if isPrime(i)])

s1=‘ABC’ s2=‘123’(for嵌套循环)
‘A1’, ‘A2’, ‘A3’, ‘B1’, ‘B2’, ‘B3’, ‘C1’, ‘C2’, ‘C3’

print([i + j for i in ‘ABC’ for j in ‘123’])

列表生成式变形-for循环嵌套

需求:讲3x3的矩阵转换成一堆数组
[
[1,2,3],
[4,5,6],
[7,8,9]
]
[1,2,3,4,5,6,7,8,9]
“”"

li = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
resLi = []
for item1 in li:

for item2 in item1:

if item2 % 2 == 0:

resLi.append(item2)

print(resLi)

print([item2 for item1 in li for item2 in item1])

from itertools import chain
print(list(chain(*li)))

列表生成器案例

将列表中所有内容都变成小写 li = [‘dasdaFSDFSFDSF’,‘dadDSADSAsdaDASsadas’]

print([i.lower() for i in li])

找出/var/log目录中,所有以.log结尾的文件名或者目录名

import os #我们经常会与文件和目录打交道,对于这些操作python提供了一个os模块,里面包含了很多操作文件和目录的函数
#print(os.listdir(’/var/log’))
print([filename for filename in os.listdir(’/var/log’) if filename.endswith(’.log’)])

字典生成式

需求1:假设有20个学生,学生分数在60~100之间,筛选出成绩在90分以上的学生

import random
stuInfo={}
for i in range(20):

name = ‘westos’ + str(i)
score = random.randint(60,100)
stuInfo[name] = score
print(stuInfo)
#stuInfo = {‘westos’+ str(i):random.randint(60,100) for i in range(20)} #字典生成式写法

highscore = {}
for name,score in stuInfo.items():

if score > 90:

highscore[name] = score

print(highscore)

#字典生成式写法

print({name:score for name,score in stuInfo.items() if score > 90})

需求2:将所有的key值变为大写

d = dict(a=1,b=2)
new_d = {}
for i in d:

new_d[i.upper()] = d[i]

print(‘key转化为大写的字典:’,new_d)

#字典生成式写法

print({k.upper():v for k,v in d.items()})

需求3:大小写key值合并,统一以小写输出

d = dict(a=2, b=1, c=2, B=9, A=10)
print({k.lower(): d.get(k.lower(), 0) + d.get(k.upper(), 0) for k in d})
for k, v in d.items():

low_k = k.lower()
if low_k not in new_d:

new_d[low_k] = v

else:

new_d[low_k] += v

print(new_d)

集合生成式

集合生成式与生成式差不多,具体参考集合与列表的区别

print({i ** 2 for i in {1, 2, 3}})
print({i ** 2 for i in {1, 2, 3, 9, 12} if i % 3 == 0})

生成器

我们知道我们可以用列表储存数据,可是当我们的数据特别大的时候建立一个列表的储存数据就会很占内存的。这时生成器就派上用场了。它可以说是一个不怎么占计算机资源的一种方法。
生成器就像是我们在做一件事,但是做到一半有事离开,这件事会中断,但是会保存现在的状态,我们回来后会继续接下来的步骤。

1.创建生成器的第一重方式
我们可以用列表推导(生成式)来生成一个生成器(列表用[],生成器用()):

nums = (x*2 for x in range(10))
nums

<generator object at 0x7fb2a6137fc0> #结果

如图:
在这里插入图片描述

生成器无法直接输出值,结果只是告诉我们这是一个生成器,所以我们用下面的方法来使用生成器,得到结果

for num in nums:
print(num)

0
2
4
6
8
10
12
14
16
18

2.创建生成器的方法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(1000)

如果在调用函数的时候,发现这个函数中有yeild
那么此时,也就不是调用函数了,而是创建了一个生成器对象

python中yield关键词。其作用和return的功能差不多,就是返回一个值给调用者,只不过有yield的函数返回值后函数依然保持调用yield时的状态,当下次调用的时候,在原先的基础上继续执行代码,直到遇到下一个yield或者满足结束条件结束函数为止。

def creat_num(all_num):

print('1 ')
a,b=0,1
current_num = 0
while current_num < all_num:

print(’ 2 ‘)
yield a #相当于暂停了程序
#print(a)
print(’ 3 ‘)
a,b = b,b+a
current_num += 1
print(’ 4 ')

obj = creat_num(5)

#此时.我们发现程序会报错(告诉我们,生成器里面没有东西了)

如果使用超出生成器存储的量,就会报错,所以一般用异常捕获来测试生成器的上限
#异常捕获

while True:

try:

ret = next(obj)
print(‘obj:’,ret)

except Exception as red:

print(red.value)
break

obj = creat_num(5)
print(obj)
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)
ret5 = next(obj)
print(ret5)

for num in obj:

print(num)
#两个生成器对象之前并没有任何关系
obj2 = creat_num(100)
print(obj2)
ret4 = next(obj2)
print(ret4)

生成器-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)

red = next(obj)

print(red)

red = obj.send(None)
print(red)

“”"
next和send得到的都是yield后面的值
不同的是send传递值而next不传递值

注意:
不能把send放在第一个,因为第一次执行程序是从开始执行
并没有值来接收send
如果你非要把send放在第一个,那么传递的值应该是None

练习

1. 列表生成式练习

  1. 找出1~10之间所有偶数, 并且返回一个列表,(包含以这个偶数为半径的圆的面积)
    import math #π是一个常数无法表示,需要调用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® for r in range(2,11,2)])

结果展示:
在这里插入图片描述

  1. 找出1~100之间所有的质数.
    “”"
    判断num是否为质数,如果是质数,返回True,否则返回False
    什么是质数?
    只能被1和本身整除的数,就是质数
    方法:
    依次判断num能被(2,num)整除
    如果能被其中其中一个数整除,不是质数
    当循环结束,都没有发现能被整除的数,那么就是质数
    “”"

def isPrime(num):

for i in range(2,num):

if num % i == 0:

return False

else:

return True

print([i for i in range(2,101) if isPrime(i)])

结果展示:
在这里插入图片描述

2.腾讯笔试题

题目描述:
给定一个正整数,编写程序计算有多少对质数的和等于输入的这个正整数,并输出结果。输
入值小于1000。
如,输入为10, 程序应该输出结果为2。(共有两对质数的和为10,分别为(5,5),(3,7))
#[2,3,5,7]

  • 输入描述:
    输入包括一个整数n,(3 ≤ n < 1000)

  • 输出描述:
    输出对数

  • 示例1 :
    输入:
    10
    输出:
    2

方法一:

def isPrime(x): # 判断x为质数

for i in range(2,x):

if x%i==0:

return False

else:

return True

ins=int(input(‘请输入整数:’))
a=[s for s in range(2,ins) if isPrime(s)]
i=0
for m in a:

for v in a:

if m+vins and mv:

i+=2

elif m+v==ins and m!=v:

i+=1

print(int(i/2))

方法2:

def isPrime(x):

for i in range(2,x):

if x%i==0:

return False

else:

return True

ins=int(input(‘请输入整数:’))
li1=[a for a in range(2,ins) if isPrime(a) and isPrime(ins-a) and a!=ins-a]
li2=[a for a in range(2,ins) if isPrime(a) and isPrime(ins-a) and a==ins-a]
print(len(li1)//2+len(li2))

方法三:

ins=int(input(‘请输入整数:’))
def isPrime(x):

for i in range(2,x):

if x%i==0:

return False

else:

return True
list=[i for i in range(2,ins) if isPrime(i)]
m=0
for i in list:
if ins-i in list and ins-i>=i:

m+=1

print(m)

方法四:

def fun(num):

count=0
for i in li_prime:

for j in li_prime[li_prime.index(i):]:

if i+j==num:

count+=1

return count

def prime(num):

for i in range(2,num):

if num%i==0:

return False

else:

return True

num_in=int(input(‘请输入整数:’))
print(prime(num_in))
li_prime=[i for i in range(1,num_in) if prime(i)]
print(li_prime)
print(fun(num_in))

结果展示:
在这里插入图片描述

作业

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.

代码:

roman=input(‘请输入罗马数字:’)
def chroman(roman):

num=0
for i in range(len(roman)):

if roman[i]==‘M’:

num+=1000

elif roman[i]==‘D’:

num+=500

elif roman[i]==‘C’:

num+=100
if roman[i+1]‘D’ or roman[i+1]‘M’:

num-=200

elif roman[i]==‘L’:

num+=50

elif roman[i]==‘X’:

num+=10
if roman[i+1]‘L’ or roman[i+1]‘C’:

num-=20

elif roman[i]==‘V’:

num+=5

else:

num+=1
if roman[i+1]‘V’ or roman[i+1]‘X’:

num-=2

return num

print(chroman(roman))

结果展示:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2.编写一个函数来查找字符串数组中的最长公共前缀
如果不存在最长公共前缀,返回空字符串 ‘’

示例 1:
输入: [“flower”,”flow”,”flight”]
输出: “fl”

示例 2:
输入: [“dog”,”racecar”,”car”]
输出: “”
解释: 输入不存在最长公共前缀

说明:所有输入只包含小写字母 a-z

代码:

def public(*args):

short=args[0]
for a in args[1:]:

if len(a)<=len(short):

short=a

li=[]
for i in range(len(short)):

k = 0
for m in args[1:]:

if m[i]==short[i]:

k+=1

if k==len(args)-1:

li.append(short[i])

return ‘’.join(li[:])

print(public(‘dogsd’,‘dogsv’,‘dogv’))

结果展示:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值