首先我们需要明确一点就是sorted()函数是作用于一个列表,对列表中的每一项元素进行排序,因为sorted本身的作用就是对元素排序,如果后面还有key=function ,则是先对列表中的每一项元素按照function进行作用,sorted()函数在对返回的结果(仍然是存在一个list中)在进行排序!理解了上面的逻辑我们就可以做题啦。
“假设我们用一组tuple表示学生名字和成绩:
L = [(‘Bob’, 75), (‘Adam’, 92), (‘Bart’, 66), (‘Lisa’, 88)]
请用sorted()对上述列表分别按名字排序:”
代码如下:
#请用sorted()对上述列表分别按名字排序:
def main():
L=[('Bob',98),('xuanxuan',90),('hehe',97),['Asas',100]]
L1=sorted(L,key=sort_byname)
print(L1)
def sort_byname(t): #t这里代表着一个元组tuple因为list中每一项不再是单纯的一个元素,而是一个tuple
return t[0].lower()
#return t[0]
main()
需要注意的是这里sort_byname()函数的作用对象是sorted()函数中的list的每一项,在这里也就是一个tuple了,由于我们是希望对名字进行排序,sort_byname()函数只需要对一个tuple返回第一个元素值 也就是名字 ,然后sorted()函数会对返回来的值 再进行排序,自然就是按名字排序了
如果是按照分数进行排序呢:
#还是上面那个例子,请用sorted()对上述列表按分数进行排序
def main():
L=[('Bob',98),('xuanxuan',90),('hehe',97),['Asas',100]]
L1=sorted(L,key=sort_byscore)
print(L1)
def sort_byscore(t):
return t[1]
main()
需要注意的是,如果一个函数的返回值仍然是一个函数或者函数的某种形式(比如说列表中的元素都是函数的形式等),那么只有当这个被返回的函数被调用时才会返回值。
现在通过例子说明一下啊:
返回函数,只有被返回的函数被调用时,才会计算里边参数的值
def count():
fs=[]
for i in range(1,4):
def f():
return i*i
fs.append(f)
return fs
def main():
f1,f2,f3=count() #因为count()返回的是一个list 里边的元素都是函数,f1,f2,f3就以此对应了list列表中的三个函数,
result1=f1() #只不过这三个函数只有等到自己被调用时f1()时才会返回原本保存在函数中参数的值
result2=f2()
result3=f3() #由于f()函数在定义时使用的时变化的i,因此前两次循环 fs列表中对应的元素--函数保存的并不是原来的1 和2 而是最后被更新到3
print(result1,result2,result3)
main()
需要说明一下,上面的代码运行之后返回的都是9 。
首先调用count()函数,返回的是fs,一个list 只不过这个list函数存放的元素不是普通的整数或者字符,在这里是函数f,主函数里f1,f2,f3=count() 后就会把三次循环结束的函数依次赋值给 f1,f2,f3,也就是现在他们三个仍是函数,并不是某个具体的值,而且这三个函数里保存着需要返回的参数i ,只有当f1() f2() f3()这样被调用时,才会依次返回值。
而且返回的值都是9并不是期望的1,4,9 原因是前一次循环的i 被后一次给覆盖了,所以最后返回的都是i=3 即3*3=9的值
那如果想要返回1,4,9呢,下面提供两种方法:
#当然如果你想输出1 4 9的话 一种方法是返回的时候直接就调用这个函数,当然这种方法返回的就不是具体的函数了
def count():
fs=[]
for i in range(1,4):
def f():
return i*i
fs.append(f()) #原本使用的是fs.append(f) 原来列表中存的是函数,现在列表中存放的是具体的值,因为f()就会调用上买你的函数,直接就会计算出来
return fs
def main():
r1,r2,r3=count()
print(r1,r2,r3)
main()
另外一种仍然采用返沪函数的代码实现如下:
#如果还想返回的是一个函数,而不是具体的值,然后向输出1,4,9,怎么办呢,只需要在返回函数的地方,让他不再使用变化的参数即可
def count():
fs=[]
def f(i): #定义一个函数,返回值仍然是一个函数
def g():
return i*i
return g
for i in range(1,4):
fs.append(f(i)) #这里调用函数之后会保存这个参数的值,而不是再下一次循环中把上一次的参数值给冲掉
return fs
def main():
f1,f2,f3=count() #count()函数返回的仍然是列表fs,里边的值仍然是函数,只不过函数里保存的参数i依次是1,2,3即下一次循环的值不会吧上一次循环的值给冲掉
print(f1(),f2(),f3()) #只有对fs列表中存放的三个函数都进行调用时才会返回值
main()
”利用闭包返回一个计数器函数,每次调用它返回递增整数:“
我在编写的时候把要调用的次数用户输入了,直接输出每次调用的结果
代码如下:
#利用闭包返回一个计数器函数,每次调用它都会返回一个递增的整数
def count(): #count()函数就是会返回一个计数器函数 increase()
def increase(n): #increase()函数里面的参数是第几次调用它
number=0
for i in range(n): #根据调用的次数返回number的值,相当于就是计数累加
number+=1
return number
return increase
def main():
n=eval(input('please input a number:')) #输入想调用计数器的次数n ,也就是说明想累加几次
for i in range(n):
f=count() #现在f就是count()函数的返回值 是一个函数 increase()
result=f(i) #increase(i) 就会返回第i次调用increase()函数累加的值
print(result,end=' ')
main()
上面的代码其实逻辑上不对,修改如下:
#利用闭包返回一个计数器函数,每次调用它都会返回一个递增的整数
#20180206里面写的不对啊,逻辑不对
def count(n): #count(n)函数就是会返回一个计数器函数increase(n),为什么这里要加一个参数,里面又重新定义了一个新的函数g呢是为了存储当前的变量值,防止下一次赋值把原来的变量值给冲掉
def increase(i): #这里i其实就是第几次调用的意思
def g():
sum=0
for j in range(i):
sum+=1
return sum
return g
return increase(n)
def main():
n=eval(input("please input a number:"))
for i in range(n):
f=count(i)
result=f()
print(result)
main()
哎,实现一个功能得想半天,,,难过
“请用匿名函数改造一下函数:”
#请用匿名函数改造下面的代码:
def is_odd(x): #判断是否为奇数
return x%2==1
def main():
print(list(filter(is_odd,range(1,20))))
main()
使用匿名函数改写为:
list(filter(lambda x:x%2==1,range(1,20))) 即可。
匿名函数中:号前面的是函数的参数,匿名函数的返回值是后面的表达式的值
“请设计一个decorator,它可作用于任何函数上,并打印该函数的执行时间:”
这个代码是参考的这位大神
import time
import functools
def log_time(func):
@functools.wraps(func)
def wrapper(*args,**kw):
start=time.time()
res=func(*args,**kw)
end=time.time()
print("%s runned in %s seconds"%(func.__name__,(end-start)*1000))
return res
return wrapper
@log_time
def f1(x,y):
time.sleep(1)
return x+y
def main():
result=f1(1,2)
print(result)
main()
下面的代码是我的一点点拓展:
#this code is to creat another feature
import functools,time
def log_time(text): #给装饰器log_time()传入一个参数
def decorator(func):
@functools.wraps(func)
def wrapper(*args,**kw):
start=time.time()
fun=func(*args,**kw)
end=time.time()
print("the progame %s runned in %s ms"%(func.__name__,(end-start)*1000))
return fun
return wrapper
return decorator
#log_time(text)(f1)
#先log_time(text) 返回一个decorator 函数,然后再decorator(f1) 在返回一个wrapper函数 至此就是@log_time("xuanxuan,,,") 和接下俩def f1()
@log_time("xuanxuan,you are a beautiful girl!")
def f1(x,y,z):
time.sleep(2) #作用是让函数暂停2s在执行,就是计算函数执行的时间的
return x+y+z
def main():
result=f1(2,3,4)
print("the result and the name of this function is {} and {} ".format(result,f1.__name__))
main()
以下两个小题的答案参考自这位大神
“请编写一个decorator,能在函数调用的前后打印出’begin call’和’end call’的日志。”
相对比较简单,直接上代码:
#在函数运行的前后输出begin call和end call:
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args,**kw):
print("begin call %s():"%func.__name__)
res=func(*args,**kw)
print("the result of the program is {}".format(res))
print("end call %s():"%func.__name__)
#resturn res
return wrapper
@log
def f2(x,y):
return x+y
def main():
f2(4,6)
print("the name of the function is :"+f2.__name__)
main()
“再思考一下能否写出一个@log的decorator,使它既支持:
@log
def f():
pass
又支持:
@log(‘execute’)
def f():
pass”
import functools
def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args,**kw):
if text!=None:
print("the text is %s and the call %s(): "%(text,func.__name__))
res=func(*args,**kw)
return res
else:
print("call %s ():"%func.__name__)
res=func(*args,**kw)
return res
return wrapper
if isinstance(text,str): #首先如果有参数 就跟原来一样直接返回decorator即可
return decorator
else: #如果没有参数 其实log(func)就是log里边其实直接传的参数就是func 返回的应该是wrapper
func=text
text=None
return decorator(func) #所以这里的应该是直接decorator(func) 返回wrapper
@log("there is a parameter in this edition")
def f1(x,y):
return x*y
def main1():
result=f1(2,3)
print("the result is {}".format(result))
print("the name of this function(no_parameter) is "+f1.__name__)
@log
def f2(x,y):
return x+y
def main2():
result=f2(5,8)
print("the result of this function(with parameter) is {}".format(result))
print("the name of this function is "+f2.__name__)
def main():
number=eval(input("please input a number to decide which the function to run:"))
if number==1:
main1()
print("run successfully!")
else:
main2()
print("Run successfully!")
main()
简单的说 引入functools.partial 之后 就可以把原来函数的参数给固定住,从而创建一个新的函数,当然对于新的函数我们仍然是可以传入新的参数值的。
import functools
def main1():
int2=functools.partial(int,base=4)
result=int2('1000000')
print(result)
def main2():
max2=functools.partial(max,100)
result=max(1,2,4,7,99)
result1=max(1,2,3,102)
print((result,result1))
#main1()
main2()