「学习笔记」3.14代码学习

来源:互联网 发布:com的域名需要备案吗 编辑:程序博客网 时间:2024/04/19 01:52

「3.14」未解决问题
ifilter
装饰器包裹函数
习题

一、昨天的习题3还是没搞懂,看到BillCode同学做的答案,也理解其思路,但是原样敲进去结果却不对。

def char2num(s):    return{'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}[s]def fn(x,y):    return x*10+ydef str2float(s):    if s.find('.')== -1:        return reduce(fn,map(char2num,s))    else:        return reduce(fn,(map(char2num,s[:s.find('.')])))+reduce(fn,(map(char2num,s[s.find('.')+1:])))/10**s.find('.')    return reduce(fn,map(char2num,s))print str2float('123.456')

运行之后输出是 123不知道哪里出了问题。
可能是精度出了问题,故将10改为10.0.

def char2num(s):    return{'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}[s]def fn(x,y):    return x*10+ydef str2float(s):    if s.find('.')== -1:        return reduce(fn,map(char2num,s))    else:        return reduce(fn,(map(char2num,s[:s.find('.')])))+reduce(fn,(map(char2num,s[s.find('.')+1:])))/10.0**s.find('.') #这里出了问题    return reduce(fn,map(char2num,s))print str2float('123.456')print str2float('0.456')

第一个运行结果正确,为123.456,但是第二个却出现了45.6,又出现了什么问题?
s.find(‘.’)是将给定的参数从前向后找到’.’的位置,如0.456,’.’出现在位置1,则相当于是’/10**1’,而事实上我们需要的是点的后几位。也就是说用s.split(‘.’)将s分成两部分,’.’前一部分和后一部分,用len(s.split(‘.’))[1]取小数点的后一部分长度,结果就对了。

def char2num(s): 
return{‘0’:0,’1’:1,’2’:2,’3’:3,’4’:4,’5’:5,’6’:6,’7’:7,’8’:8,’9’:9}[s]
def fn(x,y):
return x*10+y
def str2float(s):
if s.find(‘.’)== -1:
return reduce(fn,map(char2num,s))
else:
return reduce(fn,(map(char2num,s[:s.find(‘.’)])))+reduce(fn,(map(char2num,s[s.find(‘.’)+1:])))/10.0**len(s.split(‘.’)[1]) #此处
return reduce(fn,map(char2num,s))
print str2float(‘0.456’)

二、filter这部分出现了问题,将教程中判断素数的方法敲了进去

def _odd_iter():    n=1    while True:        n=n+2        yield ndef _not_divisible(n):    return lambda x:x%n>0def primes():    yield 2    it=_odd_iter()    while True:        n=next(it)        yield n        it=filter(_not_divisible(n),it)for n in primes():    if n <50:        print(n)    else:        break

不可思议的一幕出现了
这里写图片描述
这个已杀死是个什么概念?为什么会出现这个问题?
才发现我用的python版本是2,教程里这部分代码是3,但是我从itertools里引用ifilter就可以了。还是不是太能理解其中的意思。而且也没有查到太多关于ifilter的介绍。

from itertools import ifilter  #此处与上不同 
def _odd_iter():
n=1
while True:
n=n+2
yield n
def _not_divisible(n):
return lambda x:x%n>0
def primes():
yield 2
it=_odd_iter()
while True:
n=next(it)
yield n
it=ifilter(_not_divisible(n),it) #
for n in primes():
if n <50:
print(n)
else:
break

三、filter()应用的问题
在做filter的练习在找回数的时候出现了一些问题:

def is_pallindrome(n): 
s=str(n)
i=0
for s[i] in s:
if s[i]==s[-i-1]:
return True
else:
return False
i=i+1
print list(filter(is_pallindrome,range(1,1000)))

运行结果报错
‘str’ object does not support item assignment 分析应该是s出了问题,在原代码中s是一个字符串,并非是列表形式,所以将代码更改为:

def is_pallindrome(n): 
s=list(str(n)) #此处将字符串改为列表形式
i=0
for s[i] in s:
if s[i]==s[-i-1]:
return True
else:
return False
i=i+1
print list(filter(is_pallindrome,range(1,1000)))

运行结果正确!!!
哈哈!虽然这是一道对于别人简单不能再简单的题,但是是我第一个独立完成,并且找到错误原因的代码。哈哈!我现在已经手舞足蹈了,看来今天的我比昨天的我有进步一点点。原来还有更简洁的写法。

三、返回函数的闭包没大看懂。

闭包是指可以包含自由(未绑定到特定对象)变量的代码块; 这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。“闭包”一词来源于以下两者的结合:要执行的代码块(由于自由变量被包含在代码块中,这些自由变量以及它们引用的对象没有被释放)和为自由变量提供绑定的计算环境(作用域)。

四、装饰器
其实廖的教程我以前看过,不过都是看到装饰器这儿就卡住了,一是没有钻研的欲望,碰到困难或是难理解就放弃了的。这是个槛儿啊。不过再深研究好像也没有那么的难。
说说我自己的理解吧。
装饰器就是给一段函数加个装饰,加个头或是加个尾,一般都是不想改变函数体里的内容或是没有权限改,就在外面加个标志。看别的同学分享的学习心得,也有点是类似于嵌套函数,或是嵌套的变种。
加的头或是尾可以是指定的值,也可以是可变的函数。理解得还不是很透彻,练习题不太会做。
看了下面的答案,大家都提到了包裹函数,又是新名词,不太懂。
习题:
请编写一个decorator,能在函数调用的前后打印出’begin call’和’end call’的日志。

再思考一下能否写出一个@log的decorator,使它既支持:

@log 
def f():
pass

又支持:

@log(‘execute’) 
def f():
pass

不会,把同学“旅行的Martin”的代码拿来借鉴一下:

def log(text): 
if isinstance(text,(str,int,float)):
def decorator(func):
def wrapper(*args,**kw):
print(‘%s %s():’%(text,func.name))
return func(*args,**kw)
return wrapper
return decorator
else:
func=text
def wrapper(*args,**kw):
print (‘call %s():’%func.name)
return func(*args,**kw)
return wrapper
@log
def f():
print ‘无添加额外日志成功’
@log(‘execute’)
def f2():
print ‘添加额外日志成功’

看了一天的代码,我现在已经眼睛都睁不开了,脑袋也是一片浆糊,不看了,脑袋不清楚了。
PS:因为是转专业学的计算机,真正的计算机基础几乎为0,所有很多语言表达得不准确,或是理解得意思不对,希望等我把这行研究明白点再回来看看写的这些能改正过来。

0 0