天天看点

python学习笔记

这个笔记是我为了把学过的python知识记录下来,以便以后查看。由于现在对python的理解还不够深入,我只会记录一些python中有些难理解的部分,而不会去做总结性的概括和归纳。随着python的不断学习,会持续更新这个笔记。

python是一种动态类型(dynamic typing)的语言, python中的变量不需要提前申明类型,变量的类型由python自己决定。

例如:

这句在python中应该理解为先生成“3”这个整型的对象,然后在用a指向这个对象。再次赋值:

此时a又指向了“5”这个对象。此时对象“3”不再有引用指向它了,python会自动将没有引用指向的对象销毁(destrcut),

释放其内存。

上面的“3”和“5”都是int型的,和float,tuple,string这些都属于不可变数据对象(immutable

object)。所以即使执行下面的语句:

虽然b指向了a所指向的对象“3”,但是由于“3”是不可变的数据对象,当对b再次赋值的时候不会改变“3”本身,而是重新生成“5”这个对像,并将b重新指向“5”。python中的变量就像一个标签(tag)贴在它所代表的对象上,当然这个标签也可以撕下来重新贴在另一个对象上。

既然有不可变的数据对象,那么也肯定有可变数据对象(mutable

object)。python的字典(dictionary)类型,就要求其中的key不可以是可变数据类型的,也就是说key不可以是列表(list),

字典(dict)等可变的数据类型。

对于可变数据类型比如列表(list), 当变量指向它的时候,情况会有些不同。考虑下面的代码:

第一行说明a绑定了一个list对象(想象tag a贴在list [1, 2, 3]上),

下面一行是将b指向a指向的列表对象即 [1, 2, 3],

到这一句都和前面的整型对象一样,但最后一句就不一样了,不是将b重新贴在"3"这个整形对象上,而是改变了list中的值,a同时也会发生改变。其实从b[2]就可以看出,因为带了个"2",

b不能再次贴在其它变量上了。

关于循环对象难免要涉及以下一些概念:生成器(generator), 迭代器(iterator), list

conprehension(表理解,没法翻译)

说生成器先从range这个最常用的内置函数说起,在python2.x版本中有:

range函数直接返回的是一个列表,range通常用于循环中,这样对于循环次数过大的语句,就必须先生成那个大列表,这样效率不高。所以很多人用xrange来代替range,且看下面代码:

xrange的用法和range几乎一模一样,只是它不直接生成一个列表,而是在每次循环的时候生成一个所需的数字用于循环。帮助中也说了这样会稍微快一点,也节省了一些内存空间。可以看到xrange函数返回的是xrange的对象,这样的对象也叫做生成器(generator)。自己也可以写生成器,通过自己写的生成器就能更加清晰地理解什么是生成器。

生成器的编写和函数类似,在需要return的地方改为yield,生成器可以有多个yield。当生成器遇到一个yield的时候会停下来,返回yield后面的值,等再次调用生成器的时候,继续刚才停下的地方执行。生成器自身又构成一个循环器,每循环一次,使用一个yield的值。上面的代码是生成斐波纳挈数列,下面我们来使用它:

或者这样使用:

这样使用斐波纳挈数列是不是显得极为方便,而且效率也很高。这样再看xrange就很容易明白什么是生成器了。(python

3.x中没有了xrange函数,range函数也不再返回一个list,而是返回一个循环对象。)

迭代器和生成器几乎就是一个概念,但具体深究,循环对象和for循环调用之间还有一个中间层,就是要将循环对象转换成迭代器(iterator)。这一转换是通过使用iter()函数实现的。但从逻辑层面上,常常可以忽略这一层,所以循环对象和迭代器常常相互指代对方。

假设你有一个列表,现在需要你生成一个每个元素是原来列表的平方的新的列表,这很容易做到:

但是python不推荐上面的写法,因为不优雅。可以这样优雅的来实现:

看下面的例子:

由于zip函数返回的也是一个循环对象,所以我们用list方法将它转化为一个列表。zip函数依次取各个参数中的一个元素组成一个新的元素。下面用一个例子来说明zip函数的用法:

上面函数的功能是输入一个矩阵,返回它的转置矩阵。