前言:一直想较为熟练地掌握一门语言,毕竟以后不管是工作还是生活都不会和计算机脱离关系,而python具有简便优雅的特点,所以决定好好学习一番。一开始参考的是《Learn Python the hard way》,虽然很通俗易懂,但是基于自己已经有一定的编程基础,所以看了一会儿便觉得不适合自己,我所需要的应该是能从更深处解释Python使用机制一类的书籍,而客观原因暂时无法接触纸质书籍,所以一切从廖雪峰老师网络教程开始研究掌握。使用的系统是Windows 10,从官网下载了Python 2.7.11的版本,文本编辑器使用的是Notepad ++,某些简短的代码验证由Windows Powershell完成。
1.1 数据类型和变量
Python中能够处理的数据类型分为:
整数
1、2、3……
浮点数
1.0,-9.1,1.2e3……进行除法的时候,即使用符号/
,精度根据运算数字进行匹配,%
符号是取余。例子如下:
>>>10/4
2
>>>10.0/4
2.5
>>>10.00/4
2.5
>>>10%3
1
字符串
'a','ab'...
必须打单引号''
或者双引号""
,需要注意的是Python不区分单双引号,和C不一样,而如果在字符串中需要有单引号或双引号该怎么办?那就是使用转义字符(escape character)\。转义字符可以转义多个很多字符,例如\n
表示换行,\t
表示制表符,\\
表示\
。
>>>print 'I\'m fine.'
I'm fine.
而比较特殊的情况是可以使用r''
表示''
内部字符串不转义,显然,单双引号不影响,r""
也一样。
>>> print r'\n'
\n
>>> print r"\\t\\"
\\t\\
关于换行,前面有\n,如果字符串内部有很多换行,可以用”’…”’表示,即:
>>> print """I
... am
... fine'''"""
I
am
fine'''
>>> print 'I\nam\nfine\'\'\''
I
am
fine'''
两种表示方法都一样。
布尔值
Python中似乎还没有关于0与~0的描述,取而代之的是True
False
,布尔值之间的运算表达式有and
or
not
。
>>> True and True
True
>>> True or False
True
>>> not True
False
空值
None
,不是Null。
数据类型还包括list,dict,tuple等等,同时也能自己创建,接下来应该有专门讲解。
变量
变量可以是以上提到的任意数据类型(包括布尔值~),变量名以英文字母开头,搭配数字和下划线_
进行命名。
几乎在所有的编程语言中,=
意味着赋值,==
则是起到判断作用,在Python中同一个变量可以反复赋值,且不需要声明变量,这就是所谓的动态语言,与之相对应的则是静态语言,例如C和Java。在对变量进行赋值的时候,其实涉及到了有关指针的内容,这在C语言中是一个重点,在Python中似乎被弱化了很多。
常量
意为不能变的变量(当然,你想变没人能阻止你- -),命名习惯为全大写。
1.2 字符串和编码
字符编码
由于计算机是美国人发明的,因此,最早只有127个字母被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII
编码(怎么读?ask2?aski?),比如大写字母A的编码是65,小写字母z的编码是122,这于是成为了字符运算的依据。
可是世界上有那么多语言文字,在进行一些解释说明或者输入输出时必然不能只是英文,所以有了Unicode标准(万国码= =)
ASCII编码和Unicode编码的区别:ASCII编码是1个字节,而Unicode编码通常是2个字节。但有的时候并不需要让每个字符占两个字节,所以为了节约,可以把Unicode编码转化为UTF-8
标准。
在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件。
浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器。
Python的字符串
Python的诞生早于Unicode标准,所以默认只支持ASCII编码,故在使用Notepad++进行编辑时,需要加上
#!/usr/bin/env python
# -*- coding: utf-8 -*-
并在格式中调整为以UTF-8无BOM格式编码
,并且需要输入Unicode格式。顺带一提,通过Windows Powershell可以在目录中直接调用.py文件,验证单独文件可以直接在Notepad++界面环境下调用cmd。
如果想查看字符对应的ASCII标准的值,可以通过函数ord()
chr()
求得。
>>>ord('b')
98
>>>chr(98)
'b'
>>> u'苹'
u'\u82f9'
>>> u'果'
u'\u679c'
>>> u'核'
u'\u6838'
>>> print u'\u82f9\u679c\u6838'
苹果核
不同编码字符串互换
'abc'
可以被当作ASCII编码,也可以被当做UTF-8,,而u'abc'
只能是Unicode,把Unicode转换为UTF-8可以使用encode('utf-8')
方法。相反,使用decode('utf-8')
方法。
>>> u'ab'.encode('utf-8')
'ab'
>>> u'苹果核'.encode('utf-8')
'\xe8\x8b\xb9\xe6\x9e\x9c\xe6\xa0\xb8'
>>> #比较一下长度
... len(u'ab')
2
>>> len('ab')
2
>>> len(u'苹果核')
3
>>> len(u'\xe8\x8b\xb9\xe6\x9e\x9c\xe6\xa0\xb8')
9
>>> print '\xe8\x8b\xb9\xe6\x9e\x9c\xe6\xa0\xb8'.decode('utf-8')
苹果核
#len()函数返回字符串的长度
Python转义字符串
以下是几种常用的转义字符:
转义字符 | 描述 |
---|---|
\(在行尾时) | 续行符 |
\ | 反斜杠符号 |
\’ | 单引号 |
\” | 双引号 |
\n | 换行符号 |
\t | 横向制表符 |
\a | 响铃 |
\b | 退格(backspace) |
格式化
当遇到如何输出随变量变化的字符串,或者再通用点的情况就是有个值一直在变化,但是需要时刻使用该值,在这种情况下,一般采用格式化字符串的方式,Python和C都是采用的%
来实现。
>>> 'I\'d like to buy %d %s' %(3,'apples')
"I'd like to buy 3 apples"
#有几个%,括号就有几个量,一个的话括号可以省略,之间用,隔开
%x
表示占位符,常见的有:
%d 整数
%f 浮点数
%s 字符串
%x 十六进制整数
%自身的转义是%%
。
格式化整数和浮点数和浮点数可以指定是否补0和整数与小数的位数,这种表示方法有点儿类似于正则表达式了。
在不清楚该用哪个占位符时,%s
基本是万能的,在替换时,如果是Unicode字符串,尽量保持一致,否则会出现如下的错误。
>>> print u'我喜欢%s。' %'pizza'
我喜欢pizza。
>>> print u'我喜欢%s。' %'披萨'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 0: ordinal not in range(128)
>>> print u'我喜欢%s。' %u'披萨'
我喜欢披萨。
1.3 list
and tuple
list
- 有序集合,可以随时添加和删改元素
>>> l = ['apple','core',1,2,True,[1,2]]
>>> len(l)
6
>>> l[0]
'apple'
>>> l[3]
2
>>>l[5]
[1,2]
>>>l[5][1]
>2
用[]
表示,间隔用,
,数据类型任意,包括嵌套,索引从0开始,-1表示最后一个。len()
函数返回list元素个数。
- 添加与删除
因为list是一个有序集合,所以能追加元素到末尾,也能指定插入与删除。空集时长度为0,但是也相当于定义了。
>>> l.append(9)
>>> l
['apple', 'core', 1, 2, True, [1, 2], 9]
>>> l.insert(0,0)
>>> l
[0, 'apple', 'core', 1, 2, True, [1, 2], 9]
>>> l.pop()
9
>>> l.pop(0)
0
>>> l[4] = False
>>> l
['apple', 'core', 1, 2, False, [1, 2]]
>>> p = []
>>> len(p)
0
tuple
tuple
和list
类似,区别在于前者在定义后就不能更改,存在指向不变这一概念,有类似于指针的概念,所以对应的一些方法(method
)不能使用。
>>> t = (1)
>>> t
1
>>> t = (1,)
>>> t
(1,)
>>> t=(1,2,[3,4])
>>> len(t)
3
>>> t[0]
1
>>> t[2][1]
4
>>> t[2][1]=5
>>> t
(1, 2, [3, 5])
>>> t.pop()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'pop'
1.4 条件判断和循环
Python使用缩进规则!Python使用缩进规则!Python使用缩进规则!重要的话说三遍!
条件判断
if <条件判断1>:
<执行1>
elif <条件判断2>:
<执行2>
elif <条件判断3>:
<执行3>
else:
<执行4>
>>> x = 10
>>> if x:
... print 'True'
...
True
只要x是非零数值、非空字符串、非空list等,就判断为True,否则为False。
循环
Python的循环有两种,一种是for...in
循环,依次把list或tuple中的每个元素迭代出来,第二种循环是while
循环,只要条件满足,就不断循环,条件不满足时退出循环。range(a,b)
函数生成a到b-1的序列list,a没有的话默认为0。
for i in range(1,11):
s = s * i
print s
s = 1
i = 1
while i < 11:
s = s * i
i = i + 1
print s
结果是一样的。
break
语句是跳出整个循环continue
语句是跳出当前循环,但是这两个都是当前的嵌套
>>> for i in range(4):
... for n in range(3):
... if n == 2:
... break
... print i,n
...
0 0
0 1
1 0
1 1
2 0
2 1
3 0
3 1
raw_input()
按理来说,raw_input()
应该是一个method,可以用来读取用户的输入,需要注意的是它读取后返回的是字符串!!!
>>> a = raw_input(':')
:12
>>> a
'12'
>>> a = int(a)
>>> a
12
上述代码中使用int()
进行了转换,以后需要注意。
1.5 dict
and set
dict
Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。
>>> d = {1:'a',2:'b'}
>>> d
{1: 'a', 2: 'b'}
>>> d[1]
'a'
>>> 1 in d
True
>>> 'a' in d
False
>>> d.get(3)
>>> d.get(3,0)
0
>>> d
{1: 'a', 2: 'b'}
>>> d.pop(2)
'b'
>>> d
{1: 'a'}
key-value并没有固定的限制,只要是数据类型都可以。
有几点需要注意的是:
- key-value一一对应,value可以被重复赋值
- 避免key不存在可以使用
in
和get
来进行判断,后者要么返回None,要么返回指定值,如1
,而Python的交互命令中返回None不显示 - 可以使用
pop()
,弹出key - key必须是不可变对象
set
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。
要创建一个set,需要提供一个list作为输入集合:
>>> s = set([1,2,1,1,3,4])
>>> s
set([1, 2, 3, 4])
可以通过add(key)
和remove(key)
进行添加与移出,但是重复的依旧会被过滤。
set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:
>>> s = set([1,2,3,4])
>>> k = set([1,2,4,6])
>>> s&k
set([1, 2, 4])
>>> s | k
set([1, 2, 3, 4, 6])
关于Python中不变对象的思考:好比说,str和tuple是不变对象,list是可变对象,但有时候需要深入理解其中的不同。我认为所谓的不变应该是变量的指向性不会发生改变,即在创建变量的时候,存在类似于指针的东西,使得变量名与变量之间产生联系,究竟改变的是什么,则需要具体讨论,可能和method与function有关,不过Python是OOP语言,一切皆为对象,那么,一切都可以赋值,这也是接下来需要重点掌握的地方。