例子“
foo = 10 / 'abc'
用字面常量除以字符串,==完全符合语法!==;但是不符合语义,因为使用数字除以字符串是没有任何意义的。
//
而不是’/’==**
次方运算*
称为重复符,不是乘号epsilon
来给表示近似范围的变量命名;如abs(a - b) < epsilon,则认为a、b近似in
来检查一个对象是否在另一个对象内出现或包含==lambda args:
函数体
foo,bar = 10, 20
先对等号右侧进行求值
foo,bar = bar, foo
Py2中的range()在生成序列的时候会一次性将序列中的所有成员都生成并放入内存,这导致较大的资源占用。Py3中的range()没有这个问题,不会一次性生成所有成员。另外,Py2可以使用xran
ge()替代range(),xrange()与Py3的range()相同。
如果在range()求值之后,在for - in 代码块内修改range()的范围,此时对range()的范围毫无影响,因为range()已经求值完成了,此时再做修改是没有效果的。
当穷举集合中不包含正确结果时,无法得到正确结果;例:求25的平方根,使用穷举法从1开始尝试,每次递增0.3,即按照1.0,1.3,1.6,…这样的序列去尝试,由于不可能得到数字5,因此这种穷举法并不能得到正确结果5。
由于==二进制数不能完美地存储浮点数字,因此存在浮点数加减时的误差==
foo = 0.0
for i in range(10):
i += 0.1
print(foo)
结果是0.99999999而不是1.0。
存储数字的原理是:有效数字+指数:如1.949的有效数字可以是1949,指数为-3(实际存储的时候要将这些数字转换为二进制值来存储);即==存储一个数就是以二进制形式存储其有效数字以及指数==。
总之,表示0.1是很困难的,只能无限接近。
==因此,10个0.1相加并不等于0.1乘上10==。与C相同,==浮点数之间比较不能直接用’==’而应该用abs(a - b) <= 0.001==。
使用
round()
可以指定浮点数保留小数点后多少位有效数字
如果一个数guess是多项式P的一个根的近似值,那么guess - P(guess)/P’(guess)就是一个更好的近似值。
如下例:
def func1():
print(something)
something = 10
func1()
# 执行到此处输出10
def func2():
print(suprise)
suprise = 10
suprise = 100
func2()
# 令人震惊的是,这里不能打印出100也当然不可能打印出10;
# 反而会打印出一个错误命令
# UnboundLocalError: local variable 'suprise' referenced before assignment
# 本地变量未绑定错误: 本地变量 '惊讶' 在赋值之前被引用了
原因分析:
- [x] 只要一个变量出现在了函数体内部,那么在函数执行前,解释器就已经确认了有这个变量的存在,此时,覆盖外部、全局所有/任何同名变量。(==函数在执行之前,其内部定义的所有变量已经在执行函数的第一行代码之前就被加载了==)
- [x] 虽然解释器在函数执行前确认了叫这个名称的变量的存在,但是只要函数没有执行到这个变量的赋值语句,那么这个变量就是没有赋值的。(==函数的第一行代码执行之前,其内部所有定义的变量都是一个没有赋值的变量并且屏蔽外部其他重名变量==)
- [x] 因此,函数内存在的变量会屏蔽外部变量让你无法引用到,这个全局/外部变量被屏蔽了,被降维成函数内部的局部变量,但是却在执行到赋值语句的时候才对它赋值,在此之前对该变量的引用是对未定义的值进行引用。
一般来说,鲁邦的Python代码,是应该努力避免变量名称冲突的。命名技巧的应用:==把你的函数内部定义的变量的名称修改一下:
- 增加下划线
- 增加前后缀
- 大小写变化
- …
如果不了解Python在函数执行前首先加载函数内部所有定义的变量这一特性,就会在命名重名的时候出现这种奇怪的错误。
def isPal(s):
if len(s) <= 1 : # 递归结束条件:len <= 1,不可能是回文
return True
else:
return s[0] == s[-1] and isPal(s[1:-1])
因为这样虽然可以不使用模块名即可引用模块内的名称,如foo.bar可以直接用bar来使用,但是这样会导致可读性降低,因为看到bar并不能完全断定bar是属于foo模块内的。另外,使用了这种import方式之后,通过模块名称来引用成员的时候会报错,提示模块名称未定义。
修改模块代码后想使之生效,可以重启Python解释器
字典的键必须满足可散列,py中内置的不可变类型都是可散列的而可变类型都是不可散列的,因此可散列的元组是符合条件的
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。
以下都是生成器:
- foo = [ x ** 2 for x in range(10)]
- yield
调用的函数内有yield时,在yield处返回,返回值是yield的表达式的值;下一次执行该函数时,从上一次yield返回的位置继续执行。
>>> def odd():
... print 'step 1'
... yield 1
... print 'step 2'
... yield 3
... print 'step 3'
... yield 5
...
>>> o = odd()
>>> o.next()
step 1
1
>>> o.next()
step 2
3
>>> o.next()
step 3
5
foo = [ x for x in range(1000000)]
def funcYield(foo):
for item in foo:
yield item
if 100 in funcYield(foo):
print(True)
检测某个值是否存在于某个集合。
==使用yileld的优点是:每次遍历集合中的一个值就返回,如果此时符号条件,那么接下来集合的其他内容就不用再遍历了,不仅节省了计算时间还节省了内存空间,因为不再需要一次性生成完整的集合、生成集合中所有元素的副本了==。
遍历图里面的所有节点,要求每个节点只能被进出一次。
欧拉证明了:除了起点和终点以外,行走过程的每个点都必须被偶数条边连接。
因此,如果所有节点都不是偶数条边的话,那么这个图是不可能实现单遍历的。
节点用一个类表示,边用一个类,其中保存了这条边连接的起点和终点。
- 数学表示
可以使用邻接矩阵或邻接表来表示。
机器学习步骤
- 观测训练数据集
- 分析训练数据集并进行扩展和建模
- 利用这个模型进行预测
监督式学习:从已有特征向量去预测未知的特征向量的对应值并进行标签分类。其数据都是已经标记的数据。
非监督式学习:特征集合/训练数据没有标记,目的是发现训练数据集合中的隐含模式。
非监督式学习又分为隐变量方法和聚类方法。
聚类就是对一组对象找到当中相似的类,相当于对它们进行分类。
常见的监督式学习应用:建立分类模型;==分类模型又称为分类器==,用于对样本进行标注,即对样本进行分类。
K最近邻分类器,又称为KNN分类器。