《Python学习手册》

  04 Oct 2014 返回


1. 数据类型 ###

1.1 序列的+ *运算

假设s=”spam”s+'xyz' 为:”spamxyz”s*3=”spamspamspam” 但+需要保证运算符两边的类型一定,字符串配字符串,列表配列表([1,2]+[3,4] 输出:[1,2,3,4]


1.2 切片

假设s=”abcde”s[1:3]=”bc”,s[1:-1]=”bcd”


1.3 模式匹配

re.match(模式串,带匹配的字符串),若未匹配到则返回None,否则返回match,如下所示使用:

import re
match = re.match('/(.*)/(.*)','/user/home')
match.groups() 
# 输出:('user','home')


1.4 字符串操作

1.4.1 基本操作

1) 连接:+,重复:*,取长度:len(字符串)
2) 判断stra是否在strb中:字符串stra in 字符串strb
3) 转换为字符串:str(数字)
4) ASCII码与字符的转换:ord(字符),chr(ASCII码)

1.4.2 分片,索引

示意图:

扩展分片: X[i: j: k] 表示:从偏移i到偏移j-1,每个k个取一次元素

s = '0123456789abcde'
s[1:10:2]        # 输出:1357
s[::2]         # 输出:02468ace
s[5:2:-1]     # 输出:543

1.4.3 修改字符串

1) 替换 .replace(匹配字符串,替换成):

s = 'splot'
s = s.replace('pl', 'pamal')
# 输出s:spamalot

2) 格式化:

'That is %d %s bird!' % (1, 'blue')
'That is {0} {1} bird!'.format(1,'dead')
'That is {number} {color} bird'.format(number=1, color='blue'})

左对齐、补零、数字位数、小数点后位数

'%+08.2f' % 2.3456        # 输出:'+0002.35'

1.4.4 查找与组合

1) 字符串查找:.find(字符串) 返回第一次出现的索引

s = 'abcabc'
s.find('c')       # 输出:2

2) 数组合成字符串:'连接符'.join(数组)

s = ['1','2','3']
''.join(s)        # 输出:'123'

3) 字符串分割成数组:.split(分隔符)

s = 'a b c'
s.split(' ')      # 输出:['a','b','c']


1.5 列表操作

假设L=[123,'spam',1.23]
1) 添加元素:append(元素),insert(索引,元素),extend(列表)

L.append('Ni')
# 输出L:[123,'spam',1.23,'Ni']
L.insert(1,9)
# 输出L:[123,9,'spam',1.23,'Ni']
L.extend([5,6])
# 输出L:[123,'spam',1.23,5,6]

2) 查找index(元素),计数count(元素)

L.index(1.23)       # 输出:2
L.count(1.23)        # 输出:1

3) 删除元素:pop(索引),remove(元素),del 列表[索引]

L.pop(2)
# 返回:1.23,输出L:[123,'spam']
L.remove(123)
# 输出L:['spam']

4) 排序sort(),反转reverse()

M = ['b','a','c']
M.sort()
# 输出M:['a','b','c']
M.reverse()
# 输出M:['c','b','a']

5) 列表解析(字典也有类似的操作)

M = [[1,2,3],[4,5,6],[7,8,9]]
col2 = [ row[1] for row in M ]
# 输出col2:[2,5,8]
col2 = [ row[1] for row in M if row[1] % 2 == 0 ]
# 输出col2:[2,8]

6) 重复

L = [4,5,6]
# 输出L * 3 :[4,5,6,4,5,6,4,5,6]
# 输出[L] * 3:[[4,5,6],[4,5,6],[4,5,6]]

7) 遍历

for item in L:
    print(item)

# 或采用偏移元素方法enumerate
for (offset,value) in enumerate(s):
    print(offset,value)


1.6 字典操作

1) 增加:D[键] =值
2) 删除 :del D[键],D.pop(键) 返回:值
3) keys()函数取出字典的所有键,组成列表

D=['a':1,'b':2,'c':3]
Ks = list(D.keys())
Ks.sort()
for key in Ks :
    print(key, '=>', D[key])
# 输出:
# a=>1
# b=>2
# c=>3

4) 判断是否存在键 in (has_key在3.x中无法用)

if not 'f' in D :
    #…

5) 获取值get(键,不存在时候的默认值)

D.get('a')
# 输出:1

6) 字典解析

D=dict( zip(['a','b','c'], [1,2,3]) )
# 输出D:{'a':1, 'b':2, 'c':3}
D = {x:x*4 for x in 'SPAM'}
# 输出D:{'A':'AAAA','P':'PPPP','S':'SSSS','M':'MMMM'}
D = dict.fromkeys(['a','b','c'], 0)
# 输出D:{'a':0,'b':0,'c':0}

7) 排序:

for k in sorted(D) :
    print(k,D[k])

8) 遍历:

for (key, value) in D.items() :
    print(key,value)


1.7 元组操作

假设T=(1,2,3,4) 1) index(元素) 查找,返回下标

T.index(4)
# 输出:3

2) count(元素) 计算元素出现次数

T.count(4)
# 输出:1

3) 注意:(40)是一个数,而(40,)才是元组

1.8 集合操作

1) 并集 |,交集 &,差 -,异或 ^,子集<与超集> union(set(..)), intersection(set(..)), issubset(..), issuperset(..) 2) 增加add(一个元素),update(set(..))

z = set(['b','d'])
z.add('spam')
# 输出z:set(['b','d','spam'])
z.update(set(['x','y']))
# 输出z:set(['x','y', 'b','d','spam'])


2. 基础语法

2.1 赋值:

a, b = 'x1', 'x2'
[a,b] = [1,2]
string = 'spam'
a,b,c = list(string[:2]) + [string[2:]]
# 输出a,b,c:('s','p'.'am')


2.2 循环else

while 循环条件 :
 if 条件 :
  break
else :
 当最后没有执行过break时,就执行的部分(即使第一次也不满足循环条件时也执行)

例如:

while x:
    if match(x[0])
        print('ok')
        break
    x = x[1:]
else :
    print('Not found')


2.3 关于range

格式:range(起始整数,结束整数(不包括),步长) 非完备遍历: for i in range(0,len(s),2):... 等价于:for c in s[::2]:...


2.4 并行遍历及函数式编程

2.4.1 zip

zip会取得一个或多个序列作为参数,然后返回元组的列表,将这些序列中的并排元素配成对。 例如:

L1 = [1,2,3,4]
L2 = [5,6,7,8]
list(zip(L1,L2))
# 输出为:[(1,5),(2,6),(3,7),(4,8)]

又如,构造字典:

dict(zip(L1,L2))
# 输出为:{1:5,2:6,3:7,4:8}

2.4.2 map

s1 = 'abc'
s2 = 'xyz1'
map(None, s1, s2)
# 输出:[(a,x),(b,y),(c,z),(None,1)](仅限2.x版本,3.x已与zip一致) 

def mymap(x):
    return x+10
list(map(mymap,[1,2,3]))
# 输出:[11,12,13]

list(zip(s1,s2))
# 输出:[(a,x),(b,y),(c,z)]

2.4.3 filter

用测试函数过滤出一些元素

list( filter((lambda x: x > 0), range(-5,5)) )
# 输出:[1,2,3,4]

2.4.4 reduce

每对元素都应用函数并运行到最后结果

reduce((lambda x,y : x + y), [1,2,3,4])
# 输出:10


2.5 传参数

1) 对于不可变对象,通过“值”传递:如整数、字符串这样的对象,无法修改,效果如同创建了一份拷贝;
2) 对于可变对象,通过“指针”传递:如列表、字典这样的对象,能够在函数内部进行原处修改;
3) 参数匹配顺序:
位置、指定变量名、*name、name、默认值**


3. Python表达式操作符

3.1 生成匿名函数 lamba

格式:lamba args: expression 该表达式创建了一个之后能够调用的函数,并返回,但不是将这个函数赋值给变量。

1) 简单例子:

lower = (lambda x,y : x if x < y else y)
lower('a','b')
# 输出:'a'

2) 与函数的一个典型例子:

def knights():
    title = 'Sir'
    action = (lambda x:title + ' ' + x)
    return action

    act = knights()
    act('robin')
# 输出:Sir robin

3) 典型应用:

key = 'got'
{'already':(lambda: 2+2),
'got':(lambda:2*4),
'one':(lambda:2**6)}[key]()
# 输出:8

3.2 三元选择表达式 x if y else z

如果满足条件y,则为x,否则为z 例如:

test = 2
result = 2 if test == 1 else 3
# 输出result:3

3.3 取整与截断取整

math.trunc(数字) 去除小数部分,变整型
math.floor(数字) 舍去法,还是浮点型

4. 生成器函数

yield可以编写送回一个值并随后从其退出的地方继续的函数,拥有yield的函数称为生成器函数。

1) 简单应用:

def gensquares(N) :
    for i in range(N) :
        yield i ** 2

for i in gensquares(5):
    print i,
# 输出:0 1 4 9 16

gensquares(4)等价于生成器表达式:(x ** 2 for x in range(4))

2) 生成器函数可以用next()获得下一个值 如:

x = gensquares(4)
next(x)
# 输出:0

3) 扩展生成器函数协议send

def gen():
    for i in range(10):
        x = yield i
        print(x)

G = gen()
next(G)
# 输出:0

G.send(77)
# 输出:77
1

5. Python中的变量引用

5.1 共享引用

5.1.1 简单变量的共享引用

a = 3
b = a
则b指向a指向的单元(即:整数3)
当a = a + 2后,a指向了整数5的单元,而b的指向不变,依旧为3

5.1.2 复合变量的共享引用

L1 = [1,2,3] 
L2 = L1
L1[0] = 24

则这时L1与L2同时引用[1,2,3],对L1[0]的修改,是在原处修改,不会重新创建一个新的列表对象,因此,结果
输出L1:[24, 2, 3] 输出L2:[24, 2, 3]

若需要L1的修改不影响L2,则在赋值L2时需要拷贝对象:
L2 = L1[:] 若是字典或元组则需要 L2 = copy.copy(L1) L2 = copy.deepcopy(L1)


5.2 判断变量是否相等

== 是值的相等判断,而 is是否指向同一个对象的判断,如:

L = [1,2,3]
M = [1,2,3]
L == M     # 输出:True
L is M        # 输出:False

# 而小的整数与字符串,因缓存机制,以上都会输出True
L = 43
M = 43
L == M     # 输出:True
L is M        # 输出:True

6. 文件操作

6.1 打开文件

file = open(路径,标示),标示'r' -- 读取,'w' -- 写入,'a' -- 追加


6.2 使用文件

1) 读取一行.readline(),若到文件尾则返回空字符串

file = open(name)
while True:
    line = file.readline()
    if not line :
        break
    print(line)

# 还可以用文件迭代器
file = open(name)
try:
for line in open(name):
        line.rstrip()   # 去除尾部的换行符
finally:
    file.close()

2) 读取全部内容:.read() -- 成一个字符串, .readlines() -- 成一个列表
3) 写入内容:.write(字符串)
4) 在文件中存储python高级对象:
存数据结构:

import pickle
D = {'a':1,'b':2}
F = open('datafile.pkl','wb')
pickle.dump(D,F)
F.close()

取数据结构:

F = open('datafile.pkl','rb')
E = pickle.load(F)  # 此时E为上面的字典

7. 模块

7.1 模块导入方法

1) import 使一个变量名引用整个模块对象,因此需要通过模块名称来得到该模块的属性,该方式比后两种更加安全,但需要冗长的模块名,如:

import module1
module1.printer("hello world!")

2) from import 将变量名复制到另一个作用域,因此能够直接在脚本中使用复制后的变量名,而不需要通过模块,如:

from module1 import printer
printer("hello world!")

from赋值变量名,而不是连接,如:

# nested1.py
x = 99
def printer(): print(x)

# nested2.py
from nested1 import x, printer
x = 88
printer()

# nested2.py 输出:99

相对导入,. 代表该目录,.. 代表父目录,如:

from . import string    # 从该目录下加载string模块

3) from import * 当使用*时,会取得模块顶层所有赋了值的变量名的拷贝,也是不需要通过模块名来引用:

from module1 import *
printer("hello world!")


7.2 import导入原理

程序在第一次导入文件时,会执行如下三个步骤:
1) 搜索到模块文件
搜索模块文件的目录是sys.path,其包括:程序主目录,PYTHONPATH环境变量目录,标准链接库目录和.pth文件的内容(存于python安装目录顶层,如C:\Python27)。
2) 编译成位码
该步骤生成.pyc文件
3) 执行模块的代码来创建其所定义的对象
当程序非第一次导入文件时,会跳过这三个步骤,而只在sys.modules表中提取内存中已经加载的模块对象。


7.3 模块重载

由于导入模块只在第一次有效,之后的import则不会有任何变化,若还需要再次导入,则使用reload()方法。

import module
# 输出:use module printer

import module
# 则不再输出

from imp import reload
reload(module)
# 输出:use module printer