高级特性
切片
==例题:==利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()
方法。
def trim(s):
while s[:1]==' ':
s=s[1:]
while s[-1:]==' ':
s=s[:-1]
return s
迭代
==例题:==请使用迭代查找一个list中最小和最大值,并返回一个tuple:
def findMinAndMax(L):
minx=L[0]
maxx=L[0]
if L==[]:
return (None,None)
else:
for i in L:
if i < minx:
minx = i
if i > maxx:
maxx = i
res=(minx,maxx)
return res
列表生成式
如果list中既包含字符串,又包含整数,由于非字符串类型没有lower()方法,所以列表生成式会报错:
>>> L = ['Hello', 'World', 18, 'Apple', None]
>>> [s.lower() for s in L]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <listcomp>
AttributeError: 'int' object has no attribute 'lower'
使用内建的isinstance
函数可以判断一个变量是不是字符串:
>>> x = 'abc'
>>> y = 123
>>> isinstance(x, str)
True
>>> isinstance(y, str)
False
==例题:==请修改列表生成式,通过添加if语句保证列表生成式能正确地执行:
L1 = ['Hello', 'World', 18, 'Apple', None]
L2 = [x.lower() for x in L1 if isinstance(x,str) ]
print(L2)
迭代器
==例题:==杨辉三角定义如下:
1
/ \
1 1
/ \ / \
1 2 1
/ \ / \ / \
1 3 3 1
/ \ / \ / \ /
1 4 6 4 1
/ \ / \ / \ / \ /
1 5 10 10 5 1
把每一行看做一个list,试写一个generator,不断输出下一行的list:
def triangles():
L = [1]
while True:
yield L
L = [1] + [L[n] + L[n + 1] for n in range(len(L) - 1)] + [1]
for x in triangles():
print(x)
if len(x)>10:
break
函数式编程
高级函数
把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。
def addfuc(x,y,f):
return f(x)+f(y)
print(addfuc(1,-3,abs))
map/reduce
==例题1:==利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:[‘adam’, ‘LISA’, ‘barT’],输出:[‘Adam’, ‘Lisa’, ‘Bart’]:
def normalize(name):
return name[:1].upper()+name[1:].lower()
pass
L1 = ['adam', 'LISA', 'barT']
L2 = list(map(normalize, L1))
print(L2)
例题2: Python提供的sum()
函数可以接受一个list并求和,请编写一个prod()
函数,可以接受一个list
并利用reduce()
求积:
def prod(L):
res = 1
for i in L:
res = res * i
return res
print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))
if prod([3, 5, 7, 9]) == 945:
print('测试成功!')
else:
print('测试失败!')
利用map
和reduce
编写一个str2float
函数,把字符串'123.456'
转换成浮点数123.456
:
from functools import reduce
num_dict = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
def char2num(s):
return num_dict[s]
def str2float(s):
s1,s2=s.split('.')
xz=reduce(lambda x,y:10*x+y,map(char2num,s1))
xf=(reduce(lambda x,y:10*x+y,map(char2num,s2))/(10**len(s2)))
x=xz+xf
return x
str2float('123.456')
filter
回数是指从左向右读和从右向左读都是一样的数,例如12321
,909
。请利用filter()
筛选出回数:
def is_palindrome(n):
num = str(n)
return num == num[::-1]
output = filter(is_palindrome, range(1, 1000))
print('1~1000:', list(output))
if list(filter(is_palindrome, range(1, 200))) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]:
print('测试成功!')
else:
print('测试失败!')
sorted
请用sorted()
对上述列表分别按名字排序:
#排序的使用
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t):
return t[0]
L2 = sorted(L, key=by_name)
print(L2)
#再按成绩从高到低排序:
def by_score(t):
return t[1]
L2 = sorted(L, key=by_score,reverse=True)
print(L2)
闭包
什么是闭包?
闭包其实是一个函数
如何创建闭包?
- 要有函数的嵌套(外部函数、内部函数)
- 内部函数中要使用外部函数变量
- 外部函数必须要有返回值,返回内部函数名
如何使用闭包?
例子
使用闭包,完成求两个数的和
def funOut(num1):
def funIn(num2):
return num2+num1
return funIn
内部函数修改外部函数的变量需要声明nonlocal
def funOut(num1):
def funIn(num2):
nonlocal num1
num+=100
return num2+num1
return funIn
例利用闭包返回一个计数器函数,每次调用它返回递增整数:
def createCounter():
x = 0
def counter():
nonlocal x
x = x + 1
return x
return counter
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
print('测试通过!')
else:
print('测试失败!')
例子使用闭包求两点之间的距离
import math
def getDisOut(x1,y1):
def getDisIn(x2,y2):
return math.sqrt((x1-x2)**2+(y1-y2)**2)
return getDisIn
getDisIn=getDisOut(0,0)
print(getDisIn(1,1))
闭包的特殊用途,可以在不修改源代码的前提下,添加日志信息
匿名函数
使用匿名函数实现对奇偶数的筛选:
L=list(filter(lambda x:x%2==1,range(1,20)))
print(L)
装饰器
装饰器其实就是一种闭包,简化闭包的访问形式。
偏函数
Python的functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function)。要注意,这里的偏函数和数学意义上的偏函数不一样。