Python

1.内部编码与指令

调试模式

命令行模式:可以直接运行.py文件,但需要切换到py文件目录下
python交互模式:在命令行模式下输入python就可以进入python交互模式,它的主要作用是调试python代码,它不是正式运行python代码的环境
e.g. 在命令行模式下输入python hello.py
用Python开发程序,完全可以一边在文本编辑器里写代码,一边开一个交互式命令窗口,在写代码的过程中,把部分代码粘到命令行去验证,事半功倍!
输入输出:print遇到逗号会输出一个空格,例如print(‘a’,’b’),输出为a b。

编程规范

1.Python使用缩进来组织代码块,请务必遵守约定俗成的习惯,坚持使用4个空格的缩进。
2.在文本编辑器中,需要设置把Tab自动转换为4个空格,确保不混用Tab和空格。
字符串可以用“”或者”括起来,但如果字符串中本身就包含’或者”,那一定要将字符串本身含有的与括起来的区分开,或者就用转义字符\,\n表示换行,\t表示制表符。print(r’*’)表示字符串不转义。使用”’…”’ 表示多行输出。
例如:print(‘\n’), 输出就是换行,print(r’\n’),输出为\n。
3.Java是静态语言,python是动态语言,在python中一个变量可以赋值成不同类型的元素。
一般使用大写字母表示一个常数(只是我们认为的常数而已,实际上是可以改变的)
4.编码问题:ASCII编码是1个字节,而Unicode编码通常是2个字节。本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8编码。
在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。在操作字符串时,我们经常遇到str和bytes的互相转换。为了避免乱码问题,应当始终坚持使用UTF-8编码对str和bytes进行转换。
将一种表达方式格式化为另一种编码时可以使用%,比如
%c ====格式化字符及其ASCII码
%s ====格式化字符串
%d ====格式化整数
%o ====格式化无符号八进制
%x ====格式化无符号十六进制数
%X ====格式化无符号十六进制数
%f ====格式化浮点数字,可指定小数点后的精度
%e ====用科学计数法格式化浮点数
%E ====作用同%e,用科学计数法格式化浮点数
%g ====根据值的大小决定使用%f或%e
%G ====作用同%g,根据值的大小决定使用%f或者%E
‘%o’%10 ,输出为12
‘%c%c%c’%’97,98,99’, 输出为abc

2.数据结构

2.1 序列

序列是一种数据结构。 Python包含6种內建的序列,使用最多的是列表和元组,字符串。其中列表可修改,元组、字符串不可修改。一般情况下列表可以替代元组。
(容器实际上包含了序列和映射(例如字典),集合)
操作:(这几项操作对所有的序列都适用,也就是说列表,元组,字符串)
1)索引:序列索引可以使用负数索引,最后一个数字的索引是-1.正数索引第一个数字是0.
序列中可以包括数字,字符串。
2)序列中字符串可以相乘,表示字符串重复多少个。例如:
ending=[‘st’]+3*[’s’]
ending
输出为 [‘st’,’s’,’s’,’s’]
3)分片
分片的第一个索引是提取部分的第一个元素的编号,最后一个索引是分片之后剩下部分的第一个元素的编号。假设第一个索引是x,第二个索引是y,则提取元素的长度为y-x(不加1)
分片的步长,假设为a,则可以表示为number[x:y:a],注意a步长在最后。
e.g. 所有的数,每5个取一个:L[::5], 原样复制:L[:]
4)序列相加
相同类型的序列可以相加,但不同类型的不行,比如说列表和字符串就不能相加
[1,2,3]+[‘q’]
输出为[1,2,3,’q’]
5)成员资格
检查一个值是否在序列中,使用in运算符。叫布尔运算符,而真值叫作布尔值。
6)长度,最小值,最大值分别是len,min,max
7)迭代,使用for …in …
比如:d = {‘a’: 1, ‘b’: 2, ‘c’: 3}
在字典中:
迭代键: for key in d:
迭代数值:for value in d.values():
键和数值一起迭代: for k,v in d.items():

2.1.1 列表

列表
1)list类型:将字符串转换为列表
2)列表操作
序列的操作都可以对列表进行,并且列表可以被修改
比如改变元素,删除元素(del),分片赋值(分片赋值可以赋值长度不等的序列,利用这个可以增加元素,删除元素)
3)列表方法
方法是一个与某些变量有紧密联系的函数,方法的调用形式是:
列表.方法(参数)
append 在列表末尾追加新的(一个)对象 eg: lst=[1,2,3] list.append(4) lst 输出为 [1,2,3,4]
count 统计某个元素在列表中出现的次数 eg: [‘to’,’be’,’or’,’not’,’to’,’be’].count(‘to’) 输出为 2
extend 在列表的末尾一次性追加另一个序列中的多个值。 eg: a=[1,2,3] a.extend([4,5,6]) a 输出为[1,2,3,4,5,6] 注意a的值被改变了
index 从列表中找出某个值第一个匹配项的索引位置 name=[‘to’,’be’,’or’,’not’,’to’,’be’] name.index(‘be’) 输出为 1
insert 将对象插入到列表中 number=[1,2,3] number.insert(2,’two’) PS:在索引为2的位置插入‘two’ number 输出为 [1,2,two,3]
pop 移除列表的一个元素,并返回该元素的值(默认是最后一个元素),对象是移除之后剩下的。 POP方法是唯一一个既能修改列表又返回元素值的列表方法。
POP方法可以实现栈(后进先出LIFO),入栈使用append,出栈使用pop
remove 移除列表中某个值的第一个匹配项
reverse 改变列表但不返回值,是一种方法。将列表中的元素反向存放。
reversed(): 这是一个函数,返回一个反向迭代子,不改变列表本身。使用for循环读出,只在第一次遍历时返回值.
sort 在原位置对列表进行排序,改变列表值,没有返回值。 x=[1,2,3] y=x 则x,y都值向这个列表,改变y也就改变了x; x=[1,2,3] y=x[:] 才将x的副本赋值给y。
sort方法含有两个可选的参数–key和reverse。 也叫关键字参数,键。可以通过使key=len表示按长度排序,reverse是一个布尔值,只有true和false两种,eg:x.sort(reverse=True)反向排列。
sorted(): 函数, 返回一个重新排列的列表却不改变原始列表。
貌似方法改变了列表本身,而函数只是返回另外一个参数。
pop()和remove(): pop是根据索引操作,remove是直接根据值来操作。
list和array的打印区别:有没有逗号:列表[[1,2,3],[2,3,4]],ndarray[[1,2,3]
[2,3,4]]

2.1.2 元组

元组tuple不可修改。元组没有方法。加逗号就可以实现元组,元组大多数时候用圆括号括起来。
1)tuple函数 与list函数相同,以一个序列作为参量并把它转换为元组
2)元组的必要性:可以在映射中当作键使用,而列表不行。
3)元组的不可修改,指的是元组的指向不可修改,可是指向的内容如果是list就可以修改该list.
区分数字与元组:(1)是数字1,(1,)是元组
input()返回的数据类型是str!所以如果输入数据的话要用int()函数转换

2.1.3 字符串

字符串同样是不可变的。对不变对象来说,调用对象自身的任何方法也不会改变该对象自身的内容,这些方法只是创建了一个新的对象并返回,这样就保证了该对象的不可变性。
1)字符串的格式化 %s 成为转换说明符
2)字符串方法:字符串从string模块中继承了很多方法
find 返回该子字符串最左边的索引
join 返回添加了元素的队列。 eg:sep=’x’ seq=[‘1’,’2’,’3’,’4’] sep.join(seq) 返回 ‘1x2x3x4’
lower 将大小写字母全部转换为小写 相关的还有title方法,string的capword函数
replace 查找并替换
split 是join的逆方法 eg:‘1x2x3x4’.split(‘x’) 返回 [‘1’,’2’,’3’,’4’]
strip 去除字符串两侧空格
translate upper maketrans

2.1.4 集合

将其它数据结构变为集合,使用set()函数。
集合与列表和元组不同,集合是无序不重复元素集。因此可以用来消除列表中的重复数据。
集合的一些操作:并集:a|b, 交集:a&b, 差集(项在a中,但不在b中):a-b,对称差集(项只在a或者b中):a^b
集合中增加一项:a.add(‘hello’), 集合中增加多项:a.update([2,3,4])
2.2 字典dict
最大的特定:內建映射
举个例子 phonebook={‘alice’:’2341’,’beth’:’4567’} 前面的名字是键(key),后面的电话号码是值,中间用:连接,键和值称为项,项之间用,隔开
dict函数 : 通过其他映射(比如其他字典)或者(键,值)这样的序列对建立字典。
使用字典可以直接为这个字典添加新的值,而不需要像列表一样先初始化它。
字典的格式化字符串
字典的方法:
clear 清楚字典中所有的项
copy 值替换时,原始字典不受影响,值增加或删除时,原始字典同样改变,如果不想要它改变,可以import deepcopy函数
fromkeys 使用给定的键建立新的字典
get 访问字典,没有元素时可以定义默认的返回值
iterms将字典元素以列表返回
has_key eg: d.has_key(k) == k in d
注意!dict内部存放的顺序和key放入的顺序是没有关系的。键不可变,因此不能是列表。

3. 编程语言

1) 读取文件
原始形式是 open(name, mode,buffering[])
name:文件名 mode:’r’:read;’w’:write;‘b’:二进制;
read() 读取原始文件并输出
readline() 每次读取一行,因为读取出来的数据是上一次读取之后剩下来的,所以for循环可以实现依次读出
e.g. for i in range(3)
print f.readline()
readlines() 读取文件的所有行并将其作为一个列表读出。
2) /表示浮点数的除,//表示整除,%表示取余数
3) 两种循环:
一种是for .. in ..
一种是while
while循环适用于设置具体的条件,而for循环适用于对某一对象依次遍历。例如:去除字符串首尾的空格
def trim(s):
while s[:1] == ’ ‘:
s = s[1:]
while s[-1:] == ’ ‘:
s = s[:-1]
return s
4) break语句可以在循环过程中直接退出循环,而continue语句可以提前结束本轮循环,并直接开始下一轮循环。这两个语句通常都必须配合if语句使用
5) 异常
创建异常与捕捉异常 try: except
6)
函数返回值:在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便。函数执行完毕也没有return语句时,自动return None。
定义函数时,需要确定函数名和参数个数;
函数参数:位置参数,默认参数,可变参数(参数个数可变),关键字参数,命名关键字参数(调用时必须有参数名,使用*)
power(5)
25
power(5, 2)
25
从上面的例子可以看出,默认参数可以简化函数的调用。设置默认参数时,有几点要注意:
一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);
二是如何设置默认参数:当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
使用默认参数有什么好处?最大的好处是能降低调用函数的难度。只有当条件与默认参数不符时才需要提供其他信息。
定义默认参数要牢记一点:默认参数必须指向不变对象!否则在每次调用的时候改变了默认参数。
为什么要设计str、None这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。
可变参数使用实现,在list或者tuple前面加上一个可以把它变成可变的int类型,在参数前面加*表示输入为int类型的可变参数。
关键字参数使用**实现,这些关键字参数在函数内部自动组装为一个dict,dict的key是参数,数值是参数值。
在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
7) 所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
8) map(function,parameter):map函数是将函数作用于参数,例如map(float,a)是将a转换为float类型,但与python2.0版本不同的是3.0的map()返回的不是列表,如果需要返回列表则在函数前加上list()
9) 列表生成式
写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来。e.g.
[x * x for x in range(1, 11)]
for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:[x * x for x in range(1, 11) if x % 2 == 0]
还可以使用两层循环,可以生成全排列:[m + n for m in ‘ABC’ for n in ‘XYZ’]
10) 生成器
1.把列表生成式的[]直接改成(),
2.一个函数的定义中包含yield关键字(用yield代替print),那么这个函数就是generator
变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
读出:1.使用next()一次读出一个数,有溢出报错的危险,2.使用for循环读出
11) 关键字and和or
python 中的and:从左到右计算表达式,若所有值均为真,则返回最后一个值,若存在假,返回第一个假值。
or也是从左到有计算表达式,返回第一个为真的值。
例如:’a’ and ’b’ 返回’b’

4. 其他模块

4.1 matplotlib

matplotlib的使用实例:
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 4)) #创建一个绘图对象, 并设置对象的宽度和高度, 如果不创建直接调用plot, Matplotlib会直接创建一个绘图对象
plt.plot([1, 2, 3, 4]) #此处设置y的坐标为[1, 2, 3, 4], 则x的坐标默认为[0, 1, 2, 3]在绘图对象中进行绘图, 可以设置label, color和linewidth关键字参数
plt.ylabel(‘some numbers’) #给y轴添加标签, 给x轴加标签用xlable
plt.title(“hello”); #给2D图加标题
plt.show() #显示2D图

有plot,subplot的时候都会自动创建一个figure对象。
fig=plt.figure(); ax=fig.add_subplot(1,1,1)
fig,axes = plt.subplots(1,1)
两种一样,但前者ax就是第一个subplot对象,而后者只是画出subplot,具体取使用axes[i,j].hist()

4.2 pandas

pandas中的Series,DataFrame都可以直接作图,使用Series.plot()
pandas中使用标签的切片运算与普通的python切片运算是不同的,其包含末尾。
DataFrame,Series的value_counts()方法可以计算出某一列中,将不同的类作为索引,其数量作为对应的数值输出。
去DataFrame中的列直接frame[‘columns’],取行用frame.ix[‘index’]
对DataFrame处理的时候默认按列操作,设置axis=1则按行操作。

4.3 numpy

*

5. python实例

5.1 汉诺塔的递归算法:

当n=1时,输出为a–>c
当n=2时,先将上面一个小的移到b,然后a–c,最后完成b–c :move(1,a,c,b),a->c,move(1,b,a,c)
当n=3时,先将上面两个移到b,将最下面一个移到c,再将上面两个移到c :move(2,a,c,b),a->c,move(2,b,a,c)
当n=4时,先将上面三个移到b,将最下面一个移到c,再将b的三个移到c :move(3,a,c,b),a->c,move(3,b,a,c)
于是有:
def move(n,a,b,c):
if n==1:
print(a,’->’,c)
else:
move(n-1,a,c,b)
print(1,a,b,c)
move(n-1,b,a,c)

5.2 利用生成器输出杨辉三角

python学习笔记(总)

6. 面对对象编程(OOP, object-oriented programming)

Python编程分为两种:面对过程编程和面向对象编程。面向过程编程将分配变量,定义函数分开执行,而面向对象编程时,这个对象包括了数据和操作数据的函数。
面向对象的设计思想是从自然界中来的,因为在自然界中,类(Class)和实例(Instance)的概念是很自然的。Class是一种抽象概念,比如我们定义的Class——Student,是指学生这个概念,而实例(Instance)则是一个个具体的Student,比如,Bart Simpson和Lisa Simpson是两个具体的Student。所以,面向对象的设计思想是抽象出Class,根据Class创建Instance。
对象的第一个方法init用来创建属性,第一个参数是self。后面的参数与创建实例的输入参数对应,创建函数时第一个参数也是self,其余跟普通函数一样,但是在调用时不需要传入self参数。
如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线,在Python中,实例的变量名如果以开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问
封装:可以将函数封装,我们并不需要知道函数具体怎么写的,只需要知道它可以完成什么操作就行了;
继承:子类可以获得父类(超类)的全部功能。
多态:继承中,子类具有多态性,它即属于这个子类,又属于父类。多态的好处是,我们只需要知道这个对象属于某一个父类,无需确切知道它的子类型,都可以放心的调用父类的方法,而具体调用时选用的方法由该类的类型决定。也就是说可以随意的调用,但又不失子类型的特殊性。
静态语言 vs 动态语言:Java是一种动态语言,它要确保传入对象是该类或它的子类。而python是动态语言,只要知道两个类内部的方法有相同的就可以调用其相同的方法,认为他们是同一种类。
判断类型:type(),isinstance(*,type),获取其方法dir(‘’),判断该类是否有某个属性:hasattr(obj,’x’)
类的属性和实例的属性,通过init定义的都是实例的属性,类属性可以直接定义,实例属性可以覆盖类属性,所以两者名字不要相同。
因此,方法与函数的概念:对class作用的方法实际上都是方法中的函数,从实例中就可以看出,比如:
a=list(‘abc’), a.append(‘d’) 等价于 a=list(‘abc’),list.append(a,’d’)

相关文章: