文章目录
博客cpen_web
练习1
示例1:实现Python的float功能 将”123.456”转化成浮点数
方法1
def func01(s):
from functools import reduce
return reduce(lambda x, y: x + y / (10 ** (len(str(y)))),map(lambda x: int(x),s.split('.')))
print(func01('123.456'))
#注:map(lambda x: int(x),s.split('.')) 保留123 456 的整型
方法2
from functools import reduce
s = "123.456"
s = s.split('.')
print(s)
b = {'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'0':0}
c1 = list(map(lambda i:b.get(i),s[0]))
c2 = list(map(lambda i:b.get(i),s[1]))
def func01(x,y):
return x*10+y
def func02(x,y):
return x/10+y
result = reduce(func01,c1) + reduce(func02,c2[::-1])/10
print(result,type(result))
示例2:filter函数:找出[1-100]能被3整除的数
result = filter(lambda x: x%3==0, range(1,101))
print(list(result))
示例3:map函数:求list[1-10]各项的平方
result = map(lambda x: x**2, range(1,11))
print(list(result))
示例4:将列表[1,4,5,9] 转换成 '1459’的字符串
a = [1,4,5,9]
b = "".join(map(str,a))
print(b)
示例5:排序
有以下列表:list1=[7, -8, 5, 4, 0, -2, -5] 正数在前负数在后 正数从小到大 负数从大到小
方法1:元组
# 有以下列表:list1=[7, -8, 5, 4, 0, -2, -5] 正数在前负数在后 整数从小到大 负数从大到小
list1 = [7, -8, 5, 4, 0, -2, -5]
list2 = sorted(list1,key=lambda x:(x<0, abs(x))) # 注:后面返回的是1个元组
#第一次key函数返回(False,7),(True,8),(False,5),(False,4),(False,0),(True,2),(True,5)
#第一次排序False在前,True在后
#第一个数值相同的时候,再比较第二个
print(list2)
#结果为 [0, 4, 5, 7, -2, -5, -8]
方法2:过滤filter
list1 = [7, -8, 5, 4, 0, -2, -5]
list2 = filter(lambda x: x<0, list1)
list3 = filter(lambda x: x>=0, list1)
list = sorted(list3) + sorted(list2, reverse = True)
print(list)
#结果为 [0, 4, 5, 7, -2, -5, -8]
result=sorted(filter(lambda x:x>=0,list1))+sorted(filter(lambda x:x<0,list1),reverse=True)
print(result)
#结果为 [0, 4, 5, 7, -2, -5, -8]
方法3:数学类方法
list1 = [7, -8, 5, 4, 0, -2, -5]
#7,15,5,4,0,9,12
print(sorted(list1, key = lambda x:max(list1) -x if x<0 else x))
#结果为 [0, 4, 5, 7, -2, -5, -8]
示例6:字符串排序
这是一个字符串排序,排序规则:小写<大写<奇数<偶数
方法:元组
# 这是一个字符串排序,排序规则:小写<大写<奇数<偶数
s = 'asdf234GDSdsf23' # 注:后面的条件放前面筛选,True在后,False在前
s2 = "".join(sorted(s, key=lambda x: (x.isdigit(),x.isdigit() and int(x) % 2 == 0,x.isupper(),x)))
print(s2) # 注:先判断是否是数字,判断是否偶数,判断是否大写
#对于a 返回(False,False,False,a)
#对于2 返回(True ,True ,False,2)
#对于G 返回(False,False,True ,G)
#对于3 返回(True ,False,False,3)
#结果为 addffssDGS33224
知识点2 字典排序
示例
>>> a = {"b":2,"c":4,"a":5,"d":3}
>>> sorted(a) # 注:字典排序,默认输出为key
['a', 'b', 'c', 'd']
>>> sorted(a.values()) # 注:对value值进行排序
[2, 3, 4, 5]
>>> sorted(a.items(), key = lambda x:x[1]) # 注:最后输出为字典,需要转换成元组
[('b', 2), ('d', 3), ('c', 4), ('a', 5)] # 注:x[1]value值,对value值进行排序
>>> dict(sorted(a.items(), key = lambda x:x[1])) # 注:x[0]也可以对Key值进行排序
{'b': 2, 'd': 3, 'c': 4, 'a': 5}
知识点3 Python推导式
Python推导式
推导式comprehensions(又称解析式),是Python的一种独有特性。推导式是可以从一个数据序列构建另一个新的数据序列的结构体。 共有三种推导,在Python2和3中都有支持:
·列表(list)推导式
·字典(dict)推导式
·集合(set)推导式
知识点4 Python推导式-列表(list)推导式
·列表(list)推导式
用[]生成list
基本格式:variable = [out_exp_res for out_exp in input_list if out_exp == 2]
·out_exp_res: 列表生成元素表达式,可以是有返回值的函数。
·for out_exp in input_list: 迭代input_list将out_exp传入out_exp_res表达式中。
·if out_exp == 2: 根据条件过滤哪些值
示例1:打印30以内能被3整除的数,放到1个列表里面
#列表推导式
#打印30以内能被3整除的数,放到1个列表里面
#之前的2种方法
li = []
for i in range(31):
if i%3 == 0:
li.append(i)
print(li)
#结果为 [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
print(list(filter(lambda x:x%3==0,range(31))))
#结果为 [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
#列表推导式
print([i for i in range(31) if i%3 == 0])
#for循环 --> if过滤 --> [i]
#跟三元运算有点像
#结果为 [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
示例2:30以内能被3整除的数的平方
#30以内能被3整除的数的平方
print([i**2 for i in range(31) if i%3 == 0])
#结果为 [0, 9, 36, 81, 144, 225, 324, 441, 576, 729, 900]
#i**2 是最终要放在列表里的元素
示例3:找出50以内的偶数(不包括50)
#找出50以内的偶数(不包括50)
print([i for i in range(50) if i%2 == 0])
#结果为 [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48]
练习5 推导式嵌套
题目1 找到嵌套列表中名字含有2个’e’的所有名字
names = [[‘Tom’, ‘Billy’, ‘Jefferson’, ‘Andrew’, ‘Wesley’, ‘Steven’, ‘Joe’],
[‘Alice’, ‘Jill’, ‘Ana’, ‘Wendy’, ‘Jennifer’, ‘Sherry’, ‘Eva’, ‘Elven’]]
示例
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva', 'Elven']]
print([ name for lst in names for name in lst if name.count("e")>=2 ])
#结果为 ['Jefferson', 'Wesley', 'Steven', 'Jennifer']
#相当于 for --> lst --> for --> name --> if
li = []
for lst in names:
for name in lst:
if name.count("e") >= 2:
li.append(name)
print(li)
#结果为 ['Jefferson', 'Wesley', 'Steven', 'Jennifer']
题目2 100以内能被3整除的数,如果是1个偶数,就取0,如果是奇数,就取这个数
示例
#100以内能被3整除的数,如果是1个偶数,就取0,如果是奇数,就取这个数
#三元运算与列表推导式
print([ 0 if i%2==0 else i for i in range(101) if i%3==0 ])
#后面的if是过滤数据的,前面的是它返回的数据
#布尔值判断
print([i if i % 2 else 0 for i in range(100) if not i%3 ])
#not i%3 被3整除为0 not 0 为True
#结果为 [0, 3, 0, 9, 0, 15, 0, 21, 0, 27, 0, 33, 0, 39, 0, 45, 0, 51, 0, 57, 0, 63, 0, 69, 0, 75, 0, 81, 0, 87, 0, 93, 0, 99]
#等式判断
print([i if i%2!=0 else 0 for i in range(100) if i%3==0])
#结果为 [0, 3, 0, 9, 0, 15, 0, 21, 0, 27, 0, 33, 0, 39, 0, 45, 0, 51, 0, 57, 0, 63, 0, 69, 0, 75, 0, 81, 0, 87, 0, 93, 0, 99]
#等价于
li = []
for i in range(100):
if i%3 == 0:
if i%2 == 0:
li.append(0)
else:
li.append(i)
知识点6 Python推导式-字典(dict)推导式
·字典(dict)推导式
字典推导和列表推导的使用方法是类似的,只不中括号该改成大括号。
基本格式:variable = {out_key:out_value for out_key,out_value in input_list if out_exp == 2}
·out_key: 返回字典结果的key
·out_value: 返回字典结果的value
·for out_key,out_value in input_list: 迭代input_list将out_exp传入out_exp_res表达式中。
·if out_exp == 2: 根据条件过滤哪些值可以。
示例1
#字典推导式
dict1 = {"a":1,"b":2,"c":3,"d":4,"ac":5}
dict2 = { k:v for k,v in dict1.items() if 'a' not in k }
print(dict2)
#结果为 {'b': 2, 'c': 3, 'd': 4}
#注:key里面不包含'a'的 生成1个新的字典
示例2
#将key转化为小写,合并大小写的key值
#{"a":6,"b":8,"c":4}
dic = {"A":1,"B":2,"c":4,"a":5,"b":6}
print({ k.lower():dic.get(k.lower(),0)+dic.get(k.upper(),0) for k in dic })
#结果为 {'a': 6, 'b': 8, 'c': 4}
#后面是过滤出需要用到的值,前面再去运算
#注:dict获取value建议使用属性get 因为可以指定默认返回值
知识点7 Python推导式-集合(set)推导式
·集合(set)推导式
它们跟列表推导式也是类似的。 唯一的区别在于它使用大括号{}。
·集合推导式,自带去重功能
示例
#集合推导式 --> 去重
lst = [-1,2,1,2,4]
set_li = {i for i in lst}
print(set_li)
#结果为 {1, 2, 4, -1}
#集合特性 天生去重
练习8
·过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
·q1 = [‘a’,‘ab’,‘abc’,‘abcd’,‘abcde’]
·求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数组成的元组列表
·期望结果:[(0,1),(0,3),(0,5), (2,1), (2,3)…]
·快速更换key和value # 期望结果:{10:‘a’, 34:‘b’}
·q3 = {‘a’: 10, ‘b’: 34}
·合并大小写对应的value值,将k统一成小写 #期望 结果:{‘a’:5, ‘b’:9, ‘c’:3}
·q4 = {‘B’:3, ‘a’:1, ‘b’:6, ‘c’:3, ‘A’:4}
题目1 过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
q1 = [‘a’,‘ab’,‘abc’,‘abcd’,‘abcde’]
示例
q1 = ['a','ab','abc','abcd','abcde']
print([ i.upper() for i in q1 if len(i)>=3 ])
#结果为 ['ABC', 'ABCD', 'ABCDE']
题目2 求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数组成的元组列表
期望结果:[(0,1),(0,3),(0,5), (2,1), (2,3)…]
示例
#分开写
print([ (i,j) for i in range(6) for j in range(6) if i%2==0 and j%2!=0 ])
#结果为 [(0, 1), (0, 3), (0, 5), (2, 1), (2, 3), (2, 5), (4, 1), (4, 3), (4, 5)]
#连在一起写
print([(x,y) for x in range(6) if x%2==0 for y in range(6) if y%2!=0])
#结果为 [(0, 1), (0, 3), (0, 5), (2, 1), (2, 3), (2, 5), (4, 1), (4, 3), (4, 5)]
题目3 快速更换key和value
q3 = {‘a’: 10, ‘b’: 34}
期望结果:{10:‘a’, 34:‘b’}
示例
#快速替换key value的值
q3 = {'a': 10, 'b': 34}
print({ k:v for v,k in q3.items() }) # 注:转化成元组
#结果为 {10: 'a', 34: 'b'}
题目4 合并大小写对应的value值,将k统一成小写
q4 = {‘B’:3, ‘a’:1, ‘b’:6, ‘c’:3, ‘A’:4}
期望结果:{‘a’:5, ‘b’:9, ‘c’:3}
示例
q4 = {'B':3, 'a':1, 'b':6, 'c':3, 'A':4}
print({ k.lower():q4.get(k.lower(),0)+q4.get(k.upper(),0) for k in dic})
#结果为 {'a': 5, 'b': 9, 'c': 3}
知识点9 Python可迭代对象
可迭代对象
实现了__iter__方法,该方法返回一个迭代器对象
判断是否为可迭代对象
·dir(b)查看是否实现了__iter__
·使用collections模块的Iterable方法
示例1:判定是不是可迭代对象
#方式1
>>> b = "123"
>>> dir(b) # 注:查看属性
'__iter__' # 注:有__iter__方法,那么它就是1个可迭代对象
#方式2:使用collections模块的Iterable方法
>>> b = "123"
>>> from collections import Iterable
>>> isinstance(b, Iterable) # 注:isinstance判断它是属于什么类
True # 注:说明它是可迭代对象
>>> isinstance(b, str) # 注:判断是否属于str类
True
示例2:fp是可迭代对象
[root@cPen_python ~]# cat test
test
test2
test3
test4
[root@cPen_python ~]# fp = open("test")
>>> fp = open("test")
>>> dir(fp)
'__iter__'
>>> from collections import Iterable
>>> isinstance(fp, Iterable)
True
知识点10 Python迭代器(iterator)
迭代器
实现了__iter__和__next__方法 就是1个迭代器
__next__不断的返回下一个值,__iter__方法返回自身
#注:迭代器都是可迭代对象
示例1:获取迭代器对象
>>> a = [1,2,3,4]
>>> dir(a)
['__iter__'] # 注:方法1
>>> b = a.__iter__() # 注:通过自身的__iter__方法 返回一个迭代器
>>> dir(b)
['__iter__', '__next__']
>>> b.__next__() # 注:通过迭代器自身的__next__方法不断返回下一个值
1
>>> b.__next__()
2
>>> b.__next__()
>>> a
[1, 2, 3, 4] # 注:方法2
>>> b = iter(a) # 注:使用iter 内建函数去返回迭代器
>>> b
<list_iterator object at 0x7f44a6cf8588>
>>> next(b) # 注:使用内建函数next获取下一个值
1
>>> next(b)
2
示例2:判断迭代器
>>> a = [1,2,3,4]
>>> b = a.__iter__()
>>> dir(b)
'__iter__', '__next__'
>>> from collections import Iterable, Iterator
>>> isinstance(b, Iterable)
True
>>> isinstance(b, Iterator)
True
知识点11 Python迭代器(iterator)
·生成无限序列
示例:生成1个无限序列
>>> from itertools import count
>>> a = count()
>>> type(a)
<class 'itertools.count'>
>>> dir(a)
'__iter__','__next__'
>>> next(a)
0
>>> next(a)
1
>>> next(a)
2
………………
>>> a = count(start=10) # 注:从10 开始
>>> next(a)
10
>>> next(a)
11
>>> next(a)
12
………………
·从一个有限序列中生成无限序列
示例
>>> from itertools import cycle
>>> import time
>>> weeks = cycle(["星期日","星期一","星期二","星期三","星期四","星期五","星期六"])
>>> print(type(weeks),weeks)
<class 'itertools.cycle'> <itertools.cycle object at 0x7f46296c6f78>
>>> for i in weeks:
... print(i)
... time.sleep(1)
...
星期日
星期一
星期二
星期三
星期四
星期五
星期六
星期日
星期一
星期二
………………
知识点12 Python生成器(genatator)
·什么是生成器-generator
生成器算得上是Python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。它不需要手动编写__iter__()和__next__()方法,只需要一个yiled关键字。
·生成器一定是迭代器(反之不成立)
·因此任何生成器也是以一种懒加载的模式生成值
·生成器表达式
·使用()生成generator, 将俩表推导式的[]改成()即可得到生成器。
·列表推导式与生成器表达式,定义和使用非常类似,但是,在(大量数据处理时)性能上相差很大
#注:建议使用生成器
#注:生成器 特殊的迭代器
#1、使用生成器表达式定义生成器
#2、使用yiel关键字定义生成器
示例:使用生成器表达式定义生成器
>>> a = (x for x in range(10**9)) # 注:生成器表达式 不断调用next 不是一次性生成
>>> next(a)
0
>>> next(a)
1
>>> a = [x for x in range(10**9)] # 注:列表推导式 一次性生成 放到内存
示例:使用生成器表达式定义生成器
>>> a = (x for x in range(0,100))
>>> dir(a)
['__iter__', '__next__']
·yield关键字
包含yield表达式的函数是特殊的函数,叫做生成器函数(generator function),被调用时将返回一个迭代器(iterator),调用时可以使用next或send(msg)
·一个生成器中可以有多个yield
·一旦遇到yield,就会保存当前状态,然后返回yield后面的值
·当生成器遇到一个yield时,会暂停运行生成器,返回yield后面的值。
·当再次调用生成器的时候,会从刚才暂停的地方继续运行,直到下一个yield。
·yield关键字:保留中间算法,下次继续执行
示例
#2、yield 关键字 --> 生成器函数
#yield不能够定义在外面
#生成器函数 碰到 yield 就返回
def get_content():
print("this is first yield")
a = 3
yield a
b = 4
print("this is second yield")
yield b + 1
c = 5
print("this is third yield")
yield c - 2
print("end......")
a = get_content()
print(dir(a)) # 注:a是迭代器
print("#########")
print(next(a))
#结果为this is first yield
#3
print("#########")
print(next(a))
#结果为this is second yield
#5
print("#########")
print(next(a))
#结果为this is third yield
#3
print("#########")
print(next(a))
#结果为end...... # 注:报错
print("#########")
# print(next(a))
#使用yield关键字,把普通函数变成生成器
练习13 使用生成器实现斐波那契数列
·yield生成器来实现斐波那契数列
示例
#使用生成器实现斐波那契数列
#1,1,2,3,5,8,13
from itertools import islice
def fib():
prev, curr = 0, 1
while True:
yield curr
print("curr is :", curr)
prev, curr = curr, curr+prev
f = fib()
# print(next(f))
# #输出 1
# print(next(f))
# #输出 curr is : 1
# #1
# print(next(f))
# #输出 curr is : 1
# #2
print(list(islice(f,0,10)))
#结果为 [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
#注:生成器 惰性求值
练习14 使用递归函数实现斐波那契数列
示例
def feb(n):
if n == 1 or n == 0:
return 1
else:
return feb(n-1)+feb(n-2) # feb(2) + feb(1)
print(feb(3)) # 需要feb(2)的出口条件即feb(0)=1
#结果为 3
知识点15 send
·send数据
除了可以使用 next() 方法来获取下一个生成的值,用户还可以使用 send() 方法将一个新的或者是被修改的值返回给生成器。除此之外,还可以使用 close() 方法来随时退出生成器。
示例
#send
def counter(start_at = 0):
count = start_at
while True: # 注:send发送的数据会赋值给val,next获取时,val值为None
val = (yield count) # 注:yield count默认没有任何返回值,count.send()给它发送返回值
# print(val) # 注:val相当于从外部接收的值,如果外部没有收到值,就为None
if val is not None:
count = val + 1
else:
count += 1
count = counter(5)
print(next(count))
#输出 5
print(next(count))
#输出 6
print(count.send(100)) # 注:返回一个新的值给生成器中的yield count
#输出 101
print(next(count))
#输出 102
count.close() # 注:关闭一个生成器
print(next(count)) # 注:报错,关闭以后不能再执行了
知识点16 yield from
·yield from
示例
# yield from
def g1(x):
yield range(x) # 注:获取1个值range(0,5)
def g2(x):
yield from range(x) # 注:遍历range里面的值 来获取
it1 = g1(5)
it2 = g2(5)
print( [ x for x in it1] )
#结果为 [range(0, 5)]
print( [ x for x in it2] )
#结果为 [0, 1, 2, 3, 4]
it1 = g1(5)
it2 = g2(5)
print(next(it1))
#结果为 range(0, 5)
# print(next(it1)) # 注:报错 生成器里的东西取完了
print(next(it2))
#结果为 0
print(next(it2))
#结果为 1